Author Topic: Is this a bug?  (Read 4842 times)

0 Members and 2 Guests are viewing this topic.

JRS

  • Guest
Re: Is this a bug?
« Reply #45 on: September 12, 2020, 02:00:55 PM »
In most BASIC languages INT() is a function to return a integer number. SB has INT and FIX to give you more granularity on how it rounds. (up / down)

Could INT be a cast and achive the same result?

Code: OxygenBasic
  1. float f=4.25
  2. sys a
  3. a=(int) f
  4. print a
  5.  

I'm spoiled as SB is a typleless scripting language and you don't have to DECLARE anything including arrays.
« Last Edit: September 12, 2020, 08:48:36 PM by John »

JRS

  • Guest
Re: Is this a bug?
« Reply #46 on: September 13, 2020, 11:45:19 AM »
Here is a remake with INT as a cast.

Code: OxygenBasic
  1.     include "$/inc/console.inc"
  2.      
  3.     dim a,b as double
  4.     global r as int
  5.     sub _print()
  6.     ====================================
  7.             if r=1 then
  8.                     printl "YES is an exact root"
  9.             else
  10.                     printl "NO it is not an exact root"
  11.             end if
  12.             printl
  13.             r=0
  14.     end sub
  15.      
  16.      
  17.     '====== MAIN ===============
  18.    do
  19.      
  20.     r=0
  21.     printl "input a number: "
  22.     'a=input()
  23.    a = ltrim rtrim Input ' per togliere caratteri da input tipo CR
  24.    if a=0 then exit do
  25. cls
  26.     b = sqrt(a)
  27.     print "a       = " a cr
  28.     print "SQRT(a) = " b cr
  29.      
  30.     printl "Text if the result = (INT) result"
  31.     if b = (int) b then
  32.              r=1
  33.     end if
  34.     _print
  35.      
  36.     printl "Text if the FRAC(result) has a fractional component"
  37.     if frac(b)=0 then
  38.             r=1
  39.     end if
  40.     _print
  41.      
  42.     printl "Text if result = TRUNC(result)"
  43.     if b=trunc(b) then
  44.             r=1
  45.     end if
  46.     _print
  47.      
  48.     printl "Test if Result - (INT) result = 0"
  49.     if b - (int) b = 0 then
  50.             r=1
  51.     end if
  52.     _print
  53.      
  54.     printl "Test if (INT) Result ^ 2 = number in input"
  55.     if (int) b * (int) b = a then
  56.             r=1
  57.     end if
  58.     _print
  59.      
  60.     loop
  61.  


a       = 25
SQRT(a) = 5

Text if the result = (INT) result
NO it is not an exact root

Text if the FRAC(result) has a fractional component
YES is an exact root

Text if result = TRUNC(result)
YES is an exact root

Test if Result - (INT) result = 0
NO it is not an exact root

Test if (INT) Result ^ 2 = number in input
NO it is not an exact root

---------------------------------------------------

a       = 3
SQRT(a) = 1.7320508075688772

Text if the result = (INT) result
NO it is not an exact root

Text if the FRAC(result) has a fractional component
NO it is not an exact root

Text if result = TRUNC(result)
NO it is not an exact root

Test if Result - (INT) result = 0
NO it is not an exact root

Test if (INT) Result ^ 2 = number in input
NO it is not an exact root


Charles Pegge

  • Guest
Re: Is this a bug?
« Reply #47 on: September 13, 2020, 05:33:41 PM »
Hi John,

Yes you can cast (int) but the effect is to treat the floating point binary as integer binary. They have different encodings

But you can use convert

Code: [Select]
uses console
double g=5/3
print "g ="     tab g cr
print "cast"    tab str((int) g) cr
print "cast"    tab str(cast int g) cr
print "convert" tab str(convert int g) cr
wait

JRS

  • Guest
Re: Is this a bug?
« Reply #48 on: September 13, 2020, 06:17:19 PM »

g =     1.6666666666666667
cast    -1431655765
cast    -1431655765
convert 2


Thanks for clearing up what a cast int is. The convert is a handy keyword.



« Last Edit: September 14, 2020, 04:37:01 PM by John »

JRS

  • Guest
Re: Is this a bug?
« Reply #49 on: September 13, 2020, 06:48:33 PM »
Here is a remake using convert int.

Code: OxygenBasic
  1.     include "$/inc/console.inc"
  2.      
  3.     dim a,b as double
  4.     global r as int
  5.     sub _print()
  6.     ====================================
  7.             if r=1 then
  8.                     printl "YES is an exact root"
  9.             else
  10.                     printl "NO it is not an exact root"
  11.             end if
  12.             printl
  13.             r=0
  14.     end sub
  15.      
  16.      
  17.     '====== MAIN ===============
  18.    do
  19.      
  20.     r=0
  21.     printl "input a number: "
  22.     'a=input()
  23.    a = ltrim rtrim Input ' per togliere caratteri da input tipo CR
  24.    if a=0 then exit do
  25. cls
  26.     b = sqrt(a)
  27.     print "a       = " a cr
  28.     print "SQRT(a) = " b cr
  29.      
  30.     printl "Text if the result = convert int result"
  31.     if b = convert int b then
  32.              r=1
  33.     end if
  34.     _print
  35.      
  36.     printl "Text if the FRAC(result) has a fractional component"
  37.     if frac(b)=0 then
  38.             r=1
  39.     end if
  40.     _print
  41.      
  42.     printl "Text if result = TRUNC(result)"
  43.     if b=trunc(b) then
  44.             r=1
  45.     end if
  46.     _print
  47.      
  48.     printl "Test if Result - convert int result = 0"
  49.     if b - convert int b = 0 then
  50.             r=1
  51.     end if
  52.     _print
  53.      
  54.     printl "Test if convert int Result ^ 2 = number in input"
  55.     if convert int b * convert int b = a then
  56.             r=1
  57.     end if
  58.     _print
  59.      
  60.     loop
  61.  


a       = 25
SQRT(a) = 5

Text if the result = convert int result
NO it is not an exact root

Text if the FRAC(result) has a fractional component
YES is an exact root

Text if result = TRUNC(result)
YES is an exact root

Test if Result - convert int result = 0
YES is an exact root

Test if convert int Result ^ 2 = number in input
YES is an exact root


Nicola

  • Guest
Re: Is this a bug?
« Reply #50 on: September 14, 2020, 12:42:21 AM »
Hi Charles.
However apparently INT () works correctly. In fact, by definition, INT returns the nearest integer. For example INT (3.49) should equal 3, while INT (3.51) should equal 4.
The test I made proves it (see the attached txt file).

Code: OxygenBasic
  1. use console
  2.  
  3. cls
  4.  
  5. double i
  6. for i=1 to 15
  7.   printl i tab sqrt(i) tab int(sqrt(i))
  8. next
  9. waitkey
  10.  

I did research and found that CAST and CONVERT are used in SQL ...
Is there a place in O2 where they are explained?
« Last Edit: September 14, 2020, 01:02:54 AM by Nicola »

Charles Pegge

  • Guest
Re: Is this a bug?
« Reply #51 on: September 14, 2020, 02:19:44 AM »
Hi Nicola,

The problems arise when putting int() into a conditional expression. I will try to improve the situation but I strongly recommend using frac or round since these enable float-float comparisions directly on the Floating point processor (FPU).

One possible solution is for o2 to intercept int() and turn it into round() :)

frac translates to one assembler instruction frac, and round translates to frndint. This is much faster than integer-float conversions.

The cast and convert keywords are briefly described in the manual.

« Last Edit: September 14, 2020, 03:51:32 AM by Charles Pegge »

Nicola

  • Guest
Re: Is this a bug?
« Reply #52 on: September 14, 2020, 05:03:03 AM »
Thanks Charlie, also for your patience.
At this point I like to see the results I get with the set of functions you have indicated to me.
For printing convenience I put the _str function. I'm sure you already have some function in o2 that does the same thing ...
Code: OxygenBasic
  1. use console
  2.  
  3. function _str(string s,int d=20) as string
  4.         function = s+ space(d-len(s))
  5. end function
  6.  
  7. cls
  8.  
  9. double N,r
  10. print "N" tab _str("sqrt(N)",22) _str("frac(sqrt(N))") _str("trunc(sqrt(N))") _str("ceil(sqrt(N))") _str("floor(sqrt(N))") cr
  11. for N=1 to 16
  12.   r=sqrt(N)
  13.   print N tab _str(r,22) _str(frac(r)) _str(trunc(r)) _str(ceil(r)) _str(floor(r)) cr
  14. next
  15. waitkey
  16.  

This is the result:

N       sqrt(N)               frac(sqrt(N))       trunc(sqrt(N))      ceil(sqrt(N))       floor(sqrt(N))
1       1                     0                   1                   1                   1
2       1.4142135623730951    0.4142135623730951  1                   2                   1
3       1.7320508075688772    0.7320508075688772  1                   2                   1
4       2                     0                   2                   2                   2
5       2.2360679774997898    0.2360679774997898  2                   3                   2
6       2.4494897427831779    0.4494897427831779  2                   3                   2
7       2.6457513110645907    0.6457513110645907  2                   3                   2
8       2.8284271247461903    0.8284271247461903  2                   3                   2
9       3                     0                   3                   3                   3
10      3.1622776601683795    0.1622776601683795  3                   4                   3
11      3.3166247903553998    0.3166247903553998  3                   4                   3
12      3.4641016151377544    0.4641016151377544  3                   4                   3
13      3.6055512754639891    0.6055512754639891  3                   4                   3
14      3.7416573867739413    0.7416573867739413  3                   4                   3
15      3.872983346207417     0.872983346207417   3                   4                   3
16      4                     0                   4                   4                   4


Hello

Charles Pegge

  • Guest
Re: Is this a bug?
« Reply #53 on: September 14, 2020, 07:43:53 AM »
You can limit the decimal places by using a second param for str():

example:
str(1/3, 5)
0.33333

Using 0 will give you rounded integer strings.

Nicola

  • Guest
Re: Is this a bug?
« Reply #54 on: September 14, 2020, 11:03:23 AM »
Great!
But what if you need some extra space?

JRS

  • Guest
Re: Is this a bug?
« Reply #55 on: September 14, 2020, 03:17:19 PM »
Does O2 have a PRINT FORMAT like function?

Charles Pegge

  • Guest
Re: Is this a bug?
« Reply #56 on: September 14, 2020, 03:50:44 PM »
We can use sprintf from msvcrt.dll.

But here is a function to support decimal-point alignment in a column, taking care of left and right spacing.

Code: [Select]
function dp_str(string num="", int wid=20, dpp=10) as string
===========================================================
  'num  number string
  'wid  column width
  'dpp  decimal point position in column
  '
  string buf 'column buffer
  int ln     'length of num
  int dp     'offset of num decimal point
  '
  buf=space(wid) ' column string
  ln=len(num)
  dp=instr(num,".")
  if dp=0 'integers
    dp=ln+1
  endif
  '
  int n=dpp-dp 'left spaces
  'check if too long
  if n<0 then n=0 'remove left space
  if ln>wid
    mid buf,1,"!!"+num 'error
  else
    mid(buf,1+n,num) 'copy number into position
  endif
  return buf
end function

'TESTS
uses console
print dp_str(pi(),30)      "|" cr
print dp_str(pi(),30,4)    "|" cr
print dp_str(str(pi(),5))  "|" cr
print dp_str(12345678)     "|" cr
print dp_str(123)          "|" cr
print dp_str(-123)         "|" cr
print dp_str(-123.45)      "|" cr
wait
« Last Edit: September 15, 2020, 02:20:00 AM by Charles Pegge »

JRS

  • Guest
Re: Is this a bug?
« Reply #57 on: September 14, 2020, 04:48:26 PM »
Charles,

It might be worth translating ScriptBasic's PRINT FORMAT function from C to O2. A function I couldn't live without.

FORMAT

Not sure how O2 would deal with a varidic like argument passing.
« Last Edit: September 14, 2020, 06:53:38 PM by John »

Charles Pegge

  • Guest
Re: Is this a bug?
« Reply #58 on: September 15, 2020, 01:53:02 AM »
Hi John,

I see that SB Format is based on sprintf.

This is a useful reference:

http://www.cplusplus.com/reference/cstdio/printf/

Variadics are supported for all msvcrt functions that use them.

Example:
Code: [Select]
uses corewin
uses console
char buf[100]
double d=pi()
char buf[100]
double d=pi()

'sprintf_s(buf,100,"floats: %4.2f %+.0e %E " cr, d, d, d)
'sprintf(buf, "floats: %4.2f %+.0e %E " cr, d, d, d)

   sprintf (buf, "Characters: %c %c ", asc("a"), 65)
   print buf cr
   sprintf (buf, "Decimals: %d %ld", 1977, 650000L)
   print buf cr
   sprintf (buf, "Preceding with blanks: %10d ", 1977)
   print buf cr
   sprintf (buf, "Preceding with zeros: %010d ", 1977)
   print buf cr
   sprintf (buf, "Some different radices: %d %x %o %#x %#o ", 100, 100, 100, 100, 100)
   print buf cr
   sprintf (buf, "floats: %4.2f %+.0e %E", double 3.1416, double 3.1416, double 3.1416)
   print buf cr
   sprintf (buf, "Width trick: %*d", 5, 10)
   print buf cr
   sprintf (buf, "%s", "A string")
   print buf cr
   print cr
wait
« Last Edit: September 15, 2020, 08:46:02 PM by Charles Pegge »

JRS

  • Guest
Re: Is this a bug?
« Reply #59 on: September 15, 2020, 03:38:54 AM »
That's close enough for me. I do use the custom SB number formatting string a lot as well. It looks like it wouldn't be too hard to create a O2 FORMAT function using sprintf and a bit of extra code to handle the numeric formatting.

Code: Script BASIC
  1. PRINT FORMAT("Line Number: %~0000~ Square root of 5 is %.3f\n", 25, SQR(5))


C:\ScriptBASIC\examples>sbc format.sb
Line Number: 0025 Square root of 5 is 2.236

C:\ScriptBASIC\examples>



The FORMAT function is in string.c SB source.
« Last Edit: September 15, 2020, 05:49:46 AM by John »