AllBASIC

BASIC User Group => Code Challenges => Topic started by: John on January 07, 2019, 01:41:16 am

Title: Simple Question
Post by: John on January 07, 2019, 01:41:16 am
Code: Script BASIC
  1. PRINT 9999999999999999.0 - 9999999999999998.0,"\n"
  2.  

What does your language return? (http://geocar.sdf1.org/numbers.html)

Script BASIC  2

At 15 decimal places SB returns the correct answer of 1.

Code: Bash
  1. $ perl6 -e 'print 9999999999999999.0-9999999999999998.0;print "\n";'
  2. 2
  3.  

Doesn't work on my Ubuntu 18.10 laptop.
Title: Re: Simple Question
Post by: AIR on January 07, 2019, 10:35:56 am
Floating point is 64bit by default, which doesn't offer the required precision for such a large number.

Using a long double, you (based on the compiler implementation) can get ~80bit precision:

num.cc
Code: C++
  1. #include <jade.hpp>
  2.  
  3. MAIN
  4.     PRINT(9999999999999999.0L - 9999999999999998.0L);
  5. END
  6.  

$ ./num
1


mbc-num.bas
Code: Text
  1. $EXECON
  2.  
  3. printf(E"%LG\n", 9999999999999999.0L - 9999999999999998.0L)
  4.  

$ ./mbc-num
1


AIR.
Title: Re: Simple Question
Post by: John on January 07, 2019, 11:16:54 am
I tried it again in SB using the FORMAT function and got the following erorr.

Code: Script BASIC
  1. PRINT FORMAT("%LG",9999999999999999.0 - 9999999999999998.0),"\n"
  2.  

jrs@jrs-laptop:~/sb/examples/test$ scriba simple.sb
(0): error &H8:The argument passed to a module function is out of the accepted range.
jrs@jrs-laptop:~/sb/examples/test$

Title: Re: Simple Question
Post by: AIR on January 07, 2019, 12:15:56 pm
The format specifier expects 'long double', but the numbers are still 'double'.  So even if it worked without the error, you would still see '2' as the result of the print statement here.

That's what the appended 'L' in my examples does, it tells the compiler that the numbers should be treated as 'long double' instead of the default 'double'...
Title: Re: Simple Question
Post by: AIR on January 07, 2019, 12:38:49 pm
I think you're out of luck with NATIVE support in SB.  It looks like it only uses Single Precision (REAL)

Quote from: SB Docs
25.202. TYPE

This function can be used to determine the type of an expression. The function returns a numeric value that describes the type of the argument. Although the numeric values are guaranteed to be the one defined here it is recommended that you use the predefined symbolic constant values to compare the return value of the function against. The function return value is the following

    SbTypeUndef 0 if the argument is undef.
    SbTypeString 1 if the argument is string.
    SbTypeReal 2 if the argument is real.
    SbTypeInteger 3 if the argument is integer.
    SbTypeArray 4 if the argument is an array.

So if you do:

Code: Script BASIC
  1. PRINT TYPE(9999999999999999.0)

It returns '2', which according to the docs is a REAL (single precision) Number.

Title: Re: Simple Question
Post by: John on January 07, 2019, 01:58:57 pm
I forgot all about TYPE. Handy keyword!
Title: Re: Simple Question
Post by: Mike Lobanovsky on January 07, 2019, 03:56:28 pm
... a REAL (single precision) Number.

To the best of my knowledge, Script BASIC "variant" variables use double precision floating point numbers, and the space allocated in their structures for storing the var values amounts to 64 bits to be able to store them. By the same token, SB is theoretically capable of incorporating 64-bit long integers but at a cost of lot of extra data type conversion routines that will have to be added to implement this functionality.

Linuxoid authentic 10-byte (80-bit) long doubles would require extending the SB "variant" structures to allow for the extra 2 bytes of meaningful data, which amounts to extra 4 bytes all in all to maintain the member fields aligned on a DWORD boundary.

Regarding real as used in Peter's docs, from my experience this term usually denotes 64-bit double precision floating point values, whereas the term float is used to denote 32-bit single precision quantities.
Title: Re: Simple Question
Post by: John on January 07, 2019, 05:39:27 pm
Welcome back Mike!
Title: Re: Simple Question
Post by: AIR on January 07, 2019, 07:24:34 pm
Hey, Mike!

Thanks for the expanded explanation.....

AIR.
Title: Re: Simple Question
Post by: Mike Lobanovsky on January 08, 2019, 10:27:04 am
Glad to be of service, guys! :D

In fact, I'm lurking at BASIC sites quite often (by tradition) even if only passively. I am not yet feeling an urge to return to BASIC coding and enjoy my time playing and listening to good old rock'n'roll and occasionally coding some 3D stuff in C++ with Patrice Terrier.

Accept my belated wishes for a merry Xmas and a happy New Year 2019!
Title: Re: Simple Question
Post by: jalih on March 04, 2019, 09:31:03 am
Code: Script BASIC
  1. PRINT 9999999999999999.0 - 9999999999999998.0,"\n"
  2.  

What does your language return? (http://geocar.sdf1.org/numbers.html)

With compile-time option: LIMITS(FIXEDDEC(31));

I can do following with my old PL/I compiler and get the correct result:

Code: [Select]
put skip list(999999999999999999999999999999.0 - 999999999999999999999999999998.0);
Title: Re: Simple Question
Post by: John on March 04, 2019, 03:31:08 pm
Quote
The number 9,223,372,036,854,775,807, equivalent to the hexadecimal value 7FFF,FFFF,FFFF,FFFF16, is the maximum value for a 64-bit signed integer in computing.
Title: Re: Simple Question
Post by: AIR on March 04, 2019, 06:52:03 pm
With GO, I get the following:

Code: Go
  1. num := 9999999999999999.0 - 9999999999999998.0
  2. fmt.Printf("num Type = %T, num Value = %g\n", num, num)

num Type = float64, num Value = 1