• Double trouble

    From Luc@21:1/5 to All on Sat Nov 26 15:29:17 2022
    An old Tcl problem has come back to haunt me.

    --------------------
    TYPES, OVERFLOW, AND PRECISION

    Conversion among internal representations for integer, floating-point,
    and string operands is done automatically as needed. For arithmetic computations, integers are used until some floating-point number is
    introduced, after which floating-point is used. For example,

    expr {5 / 4}

    returns 1, while
    expr {5 / 4.0}
    expr {5 / ( [string length "abcd"] + 0.0 )}

    both return 1.25. Floating-point values are always returned with a "."
    or an e so that they will not look like integer values. For example,

    expr {20.0/5.0}

    returns 4.0, not 4.
    --------------------


    That sounds like a horrible pitfall to me.

    I've been writing some code, stunned because a certain division operation
    was adamantly returning 0. It took me some time to realize I had to convert
    at least one of the numbers into float:

    set ::tcl_precision 8
    set x [::tcl::mathfunc::double $x]
    set result [expr $x / $y]

    I don't really mind doing that, but what if I run a series of calculations whose numbers I cannot predict and a couple of integers are the results of
    some of those calculations and they end up being calculated against each
    other and Tcl outputs an incorrect integer result merely because those
    two numbers happened to be integers?

    That's how trains get derailed and spaceships explode, isn't it?

    What do you sage Tclers have to say about this?

    --
    Luc


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rich@21:1/5 to Luc on Sat Nov 26 18:44:10 2022
    Luc <[email protected]> wrote:
    I've been writing some code, stunned because a certain division operation
    was adamantly returning 0. It took me some time to realize I had to convert at least one of the numbers into float:

    set ::tcl_precision 8
    set x [::tcl::mathfunc::double $x]
    set result [expr $x / $y]

    I don't really mind doing that, but what if I run a series of calculations whose numbers I cannot predict and a couple of integers are the results of some of those calculations and they end up being calculated against each other and Tcl outputs an incorrect integer result merely because those
    two numbers happened to be integers?

    That's how trains get derailed and spaceships explode, isn't it?

    What do you sage Tclers have to say about this?

    For any expr's where you want fractional answers, and you are not 100%
    sure at least one input is always going to be a float, always wrap a
    'double' around at least one part of the expression:

    set answer [expr {double($x) / $y + $z}]

    If x is already a float, the double() effectively becomes a no-op. If x is integer, the double() promotes it to float.

    And please don't suggest that Tcl should just promote to float for all
    expr operations. Down that path lies Javascript and it's lack of
    integer support entirely. And that path is haunted by a different set
    of deamons ready to poke you with their red hot pitchforks when you do
    other math operations.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Torsten Berg@21:1/5 to Rich on Sat Nov 26 15:58:26 2022
    Yes, you are right. I just try to remind myself all the time that Tcl works like C in this respect and when I do a division I make sure to explicitly make one of the numbers a float using double().

    On Saturday, November 26, 2022 at 7:44:14 PM UTC+1, Rich wrote:
    Luc <[email protected]> wrote:
    I've been writing some code, stunned because a certain division operation was adamantly returning 0. It took me some time to realize I had to convert at least one of the numbers into float:

    set ::tcl_precision 8
    set x [::tcl::mathfunc::double $x]
    set result [expr $x / $y]

    I don't really mind doing that, but what if I run a series of calculations whose numbers I cannot predict and a couple of integers are the results of some of those calculations and they end up being calculated against each other and Tcl outputs an incorrect integer result merely because those
    two numbers happened to be integers?

    That's how trains get derailed and spaceships explode, isn't it?

    What do you sage Tclers have to say about this?
    For any expr's where you want fractional answers, and you are not 100%
    sure at least one input is always going to be a float, always wrap a
    'double' around at least one part of the expression:

    set answer [expr {double($x) / $y + $z}]

    If x is already a float, the double() effectively becomes a no-op. If x is integer, the double() promotes it to float.

    And please don't suggest that Tcl should just promote to float for all
    expr operations. Down that path lies Javascript and it's lack of
    integer support entirely. And that path is haunted by a different set
    of deamons ready to poke you with their red hot pitchforks when you do
    other math operations.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)