• [ksh] 64 bit long integer type

    From Janis Papanagnou@21:1/5 to All on Fri Sep 8 15:50:17 2023
    Usually it is sufficient for me to work in Kornshell with integers
    (typeset -i) that support 32 bit (signed) data.

    Now playing with long integers (typeset -li) and 64 bit data I got
    puzzled about the results... (the two lines marked with "???")

    typeset -i x=$(getconf UINT_MAX) # -1 fff..ff
    typeset -i x=$(getconf ULONG_MAX) # 0 doesn't fit
    typeset -li x=$(getconf UINT_MAX) # 4294967295 positive in '-li'
    typeset -li x=$(getconf ULONG_MAX) # -9223372036854775808 ???
    typeset -li16 x=$(getconf ULONG_MAX) # 16#8000000000000000 ???
    getconf ULONG_MAX # 18446744073709551615 fff..ff
    typeset -li x=16#ffffffffffffffff # -1

    What conversion/truncation/whatever happens when assigning a
    ULONG_MAX (which is an all '1's number) to a long int [signed]
    type (where only the highest bit gets set, that obviously defines
    the minimum signed value)?

    Note that for 'typeset -i' and UINT_MAX it is an all '1's binary
    number, the decimal -1. And 'typeset -li' is capable of carrying
    64 '1' bits.

    (BTW; there's no overflow error indication reported or a RC>0.)

    Janis

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Janis Papanagnou@21:1/5 to Janis Papanagnou on Fri Sep 8 16:20:14 2023
    On 08.09.2023 15:50, Janis Papanagnou wrote:
    Usually it is sufficient for me to work in Kornshell with integers
    (typeset -i) that support 32 bit (signed) data.

    Now playing with long integers (typeset -li) and 64 bit data I got
    puzzled about the results... (the two lines marked with "???")

    typeset -i x=$(getconf UINT_MAX) # -1 fff..ff
    typeset -i x=$(getconf ULONG_MAX) # 0 doesn't fit
    typeset -li x=$(getconf UINT_MAX) # 4294967295 positive in '-li' typeset -li x=$(getconf ULONG_MAX) # -9223372036854775808 ???
    typeset -li16 x=$(getconf ULONG_MAX) # 16#8000000000000000 ???
    getconf ULONG_MAX # 18446744073709551615 fff..ff typeset -li x=16#ffffffffffffffff # -1

    Using unsigned types may shed some light on the issue...

    $ typeset -lui x=$(getconf ULONG_MAX) ; echo $x
    9223372036854775808

    ...not that this result wouldn't open more/other questions.


    What conversion/truncation/whatever happens when assigning a
    ULONG_MAX (which is an all '1's number) to a long int [signed]
    type (where only the highest bit gets set, that obviously defines
    the minimum signed value)?

    Note that for 'typeset -i' and UINT_MAX it is an all '1's binary
    number, the decimal -1. And 'typeset -li' is capable of carrying
    64 '1' bits.

    (BTW; there's no overflow error indication reported or a RC>0.)

    Janis


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Janis Papanagnou@21:1/5 to Janis Papanagnou on Sun Sep 10 16:00:32 2023
    It seems the below observed output is the result of a _float based_
    long-int math. Ksh's man page says in chapter Arithmetic Evaluation:
    "Evaluations are performed using double precision floating point
    arithmetic or long double precision floating point for systems
    that provide this data type."
    Results seem thus be system dependent and (on my system) [unsigned]
    long integer calculations should not be done with values greater than 9223372036854775807 (if not less than that; I haven't yet confirmed
    the reliability), and 64 bit certainly aren't supported.

    typeset UINT_MAX ULONG_MAX (expected)
    4294967295 18446744073709551615

    -i -1 0
    -ui 4294967295 0
    -li 4294967295 -9223372036854775808 (-1)
    -lui 4294967295 9223372036854775808 (18446744073709551615
    or 9223372036854775807)


    On 08.09.2023 16:20, Janis Papanagnou wrote:
    On 08.09.2023 15:50, Janis Papanagnou wrote:
    Usually it is sufficient for me to work in Kornshell with integers
    (typeset -i) that support 32 bit (signed) data.

    Now playing with long integers (typeset -li) and 64 bit data I got
    puzzled about the results... (the two lines marked with "???")

    typeset -i x=$(getconf UINT_MAX) # -1 fff..ff
    typeset -i x=$(getconf ULONG_MAX) # 0 doesn't fit
    typeset -li x=$(getconf UINT_MAX) # 4294967295 positive in '-li'
    typeset -li x=$(getconf ULONG_MAX) # -9223372036854775808 ???
    typeset -li16 x=$(getconf ULONG_MAX) # 16#8000000000000000 ???
    getconf ULONG_MAX # 18446744073709551615 fff..ff
    typeset -li x=16#ffffffffffffffff # -1

    Using unsigned types may shed some light on the issue...

    $ typeset -lui x=$(getconf ULONG_MAX) ; echo $x
    9223372036854775808

    ...not that this result wouldn't open more/other questions.


    What conversion/truncation/whatever happens when assigning a
    ULONG_MAX (which is an all '1's number) to a long int [signed]
    type (where only the highest bit gets set, that obviously defines
    the minimum signed value)?

    Note that for 'typeset -i' and UINT_MAX it is an all '1's binary
    number, the decimal -1. And 'typeset -li' is capable of carrying
    64 '1' bits.

    (BTW; there's no overflow error indication reported or a RC>0.)

    Janis



    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Janis Papanagnou@21:1/5 to Janis Papanagnou on Sun Sep 10 17:21:58 2023
    It gets even more interesting...

    $ typeset -li x=9223372036854775807 ; echo $((x))
    9223372036854775807
    $ typeset -li x=9223372036854775808 ; echo $((x))
    -9223372036854775808

    $ typeset -li x=10#9223372036854775807 ; echo $((x))
    9223372036854775807
    $ typeset -li x=10#9223372036854775808 ; echo $((x))
    ksh: typeset: 10#9223372036854775808: arithmetic syntax error

    $ typeset -li x=$(getconf ULONG_MAX) ; echo $((x))
    -9223372036854775808
    $ typeset -li x=10#$(getconf ULONG_MAX) ; echo $((x))
    ksh: typeset: 10#18446744073709551615: arithmetic syntax error

    ...you can trigger an error message (which is good!) by explicitly
    specifying the numeric base '10#' with the number.


    On 10.09.2023 16:00, Janis Papanagnou wrote:
    It seems the below observed output is the result of a _float based_
    long-int math. Ksh's man page says in chapter Arithmetic Evaluation:
    "Evaluations are performed using double precision floating point
    arithmetic or long double precision floating point for systems
    that provide this data type."
    Results seem thus be system dependent and (on my system) [unsigned]
    long integer calculations should not be done with values greater than 9223372036854775807 (if not less than that; I haven't yet confirmed
    the reliability), and 64 bit certainly aren't supported.

    typeset UINT_MAX ULONG_MAX (expected)
    4294967295 18446744073709551615

    -i -1 0
    -ui 4294967295 0
    -li 4294967295 -9223372036854775808 (-1)
    -lui 4294967295 9223372036854775808 (18446744073709551615
    or 9223372036854775807)


    On 08.09.2023 16:20, Janis Papanagnou wrote:
    On 08.09.2023 15:50, Janis Papanagnou wrote:
    Usually it is sufficient for me to work in Kornshell with integers
    (typeset -i) that support 32 bit (signed) data.

    Now playing with long integers (typeset -li) and 64 bit data I got
    puzzled about the results... (the two lines marked with "???")

    typeset -i x=$(getconf UINT_MAX) # -1 fff..ff
    typeset -i x=$(getconf ULONG_MAX) # 0 doesn't fit
    typeset -li x=$(getconf UINT_MAX) # 4294967295 positive in '-li'
    typeset -li x=$(getconf ULONG_MAX) # -9223372036854775808 ???
    typeset -li16 x=$(getconf ULONG_MAX) # 16#8000000000000000 ???
    getconf ULONG_MAX # 18446744073709551615 fff..ff
    typeset -li x=16#ffffffffffffffff # -1

    Using unsigned types may shed some light on the issue...

    $ typeset -lui x=$(getconf ULONG_MAX) ; echo $x
    9223372036854775808

    ...not that this result wouldn't open more/other questions.


    What conversion/truncation/whatever happens when assigning a
    ULONG_MAX (which is an all '1's number) to a long int [signed]
    type (where only the highest bit gets set, that obviously defines
    the minimum signed value)?

    Note that for 'typeset -i' and UINT_MAX it is an all '1's binary
    number, the decimal -1. And 'typeset -li' is capable of carrying
    64 '1' bits.

    (BTW; there's no overflow error indication reported or a RC>0.)

    Janis




    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Martijn Dekker@21:1/5 to All on Fri Sep 15 19:42:29 2023
    Op 10-09-2023 om 15:00 schreef Janis Papanagnou:
    It seems the below observed output is the result of a_float based_
    long-int math. Ksh's man page says in chapter Arithmetic Evaluation:
    "Evaluations are performed using double precision floating point
    arithmetic or long double precision floating point for systems
    that provide this data type."

    I can certainly see the flaws of that design, but I'm afraid it's pretty much set in stone. I'm reluctant to mess with the arithmetic evaluation subsystem, which (like many things in the AT&T ksh code base) is very hard to understand.

    --
    || modernish -- harness the shell
    || https://github.com/modernish/modernish
    ||
    || KornShell lives!
    || https://github.com/ksh93/ksh

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Cyrille Lefevre@21:1/5 to Janis Papanagnou on Fri Oct 27 02:00:29 2023
    On 08/09/2023 at 15:50, Janis Papanagnou wrote :
    Usually it is sufficient for me to work in Kornshell with integers
    (typeset -i) that support 32 bit (signed) data.

    Now playing with long integers (typeset -li) and 64 bit data I got
    puzzled about the results... (the two lines marked with "???")

    typeset -i x=$(getconf UINT_MAX) # -1 fff..ff
    typeset -i x=$(getconf ULONG_MAX) # 0 doesn't fit
    typeset -li x=$(getconf UINT_MAX) # 4294967295 positive in '-li' typeset -li x=$(getconf ULONG_MAX) # -9223372036854775808 ???
    typeset -li16 x=$(getconf ULONG_MAX) # 16#8000000000000000 ???
    getconf ULONG_MAX # 18446744073709551615 fff..ff typeset -li x=16#ffffffffffffffff # -1

    What conversion/truncation/whatever happens when assigning a
    ULONG_MAX (which is an all '1's number) to a long int [signed]
    type (where only the highest bit gets set, that obviously defines
    the minimum signed value)?

    Note that for 'typeset -i' and UINT_MAX it is an all '1's binary
    number, the decimal -1. And 'typeset -li' is capable of carrying
    64 '1' bits.

    (BTW; there's no overflow error indication reported or a RC>0.)

    Janis

    Hi,

    consider filling a bug report here https://github.com/ksh93/ksh/issues

    Regards,

    Cyrille Lefevre.
    --
    mailto:Cyrille.Lefevre-news%nospam@laposte.net.invalid
    remove "%nospam" and ".invalid" to answer me.

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