Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Big number division (overflow check in JIT?) #36

Open
bartolsthoorn opened this issue Jul 18, 2013 · 4 comments
Open

Big number division (overflow check in JIT?) #36

bartolsthoorn opened this issue Jul 18, 2013 · 4 comments

Comments

@bartolsthoorn
Copy link

# true:
((10 / 2) == 5, "\n") join print

# Returns false, should be true
((60000000000 / 2) == 30000000000, "\n") join print
((60e+9 / 2) == 30000000000, "\n") join print
((60e+9 / 2) == 30e+9, "\n") join print
((60e+9 / 2) == 30e+9, "\n") join print
((60e+9 / 2e+0) == 30e+9, "\n") join print

Integer range is probably lacking, but how do I cast/force a long/double in potion? I tried using the scientific notation, but to no avail.

@rurban
Copy link
Member

rurban commented Jul 18, 2013

use integer

$ ./potion -B -V -e '(60000000000 / 2) == 30000000000'

-- parsed --
code (eq (expr (table (div (expr (value (60000000000 nil nil)) expr (value (2 nil nil))))) expr (value (30000000000 nil nil))))
-- compiled --
; function definition: 0x7f99e05b9c58 ; 24 bytes
; () 2 registers
.value 60000000000 ; 0
.value 30000000000 ; 1
[1] loadk    0 0    ; 60000000000
[2] loadpn   1 5    ; 2
[3] div      0 1    
[4] loadk    1 1    ; 30000000000
[5] eq       0 1    
[6] return   0      
; function end
-- vm returned 0x6 (fixed=71768, actual=83816, reserved=262144) --
true

$ ./potion -B -V -e '(60e+9 / 2) == 30000000000'

-- parsed --
code (eq (expr (table (div (expr (value (60000000000.0 nil nil)) expr (value (2 nil nil))))) expr (value (30000000000 nil nil))))
-- compiled --
; function definition: 0x7f613534dcb0 ; 24 bytes
; () 2 registers
.value 60000000000.0 ; 0
.value 30000000000 ; 1
[1] loadk    0 0    ; 60000000000.0
[2] loadpn   1 5    ; 2
[3] div      0 1    
[4] loadk    1 1    ; 30000000000
[5] eq       0 1    
[6] return   0      
; function end
-- vm returned 0x2 (fixed=71768, actual=83928, reserved=262144) --
false

exponential notation 60e+9 is always expanded to double.
use integer to cast it.

like with my enhanced version:
$ bin/potion -B -Dt -e '(60e+9 integer / 2) == 30000000000'
-- run-time --
[ 1] loadk 0 0 ; 60000000000.0
[ 2] move 1 0 ; 60000000000.0
[ 3] loadk 0 1 ; integer
[ 4] bind 0 1 ; function()
[ 5] loadpn 2 0 ; nil
[ 6] call 0 2 ; 60000000000
[ 7] loadpn 1 5 ; 2
[ 8] div 0 1 ; 30000000000
[ 9] loadk 1 2 ; 30000000000
[10] eq 0 1 ; true
[11] return 0 ; true

@rurban rurban closed this as completed Jul 18, 2013
@rurban
Copy link
Member

rurban commented Jul 18, 2013

Sorry. To answer your original question: cast to double is done with number.

$  bin/potion -B -Dt -e '(60e+9 / 2) number == 30000000000.0'
-- run-time --
[ 1] loadk    0 0   ; 60000000000.0
[ 2] loadpn   1 5   ; 2
[ 3] div      0 1   ; 30000000000.0
[ 4] loadk    1 1   ; 30000000000.0
[ 5] eq       0 1   ; false
[ 6] return   0     ; false

Looks bad.
Trying 1e-6 precision, there is a problem with the comparison operators:

$  bin/potion -B -Dt -e 'a=(60e+9 / 2) - 30000000000.0
a abs < 1e-6'
-- run-time --
[ 1] loadk    0 0   ; 60000000000.0
[ 2] loadpn   1 5   ; 2
[ 3] div      0 1   ; 30000000000.0
[ 4] loadk    1 1   ; 30000000000.0
[ 5] sub      0 1   ; 0.0
[ 6] setlocal 0 0   ; 0.0
[ 7] getlocal 0 0   ; 0.0
[ 8] move     1 0   ; 0.0
[ 9] loadk    0 2   ; abs
[10] bind     0 1   ; function()
[11] loadpn   2 0   ; nil
[12] call     0 2   ; 0.0
[13] loadk    1 3   ; 0.000001
[14] lt       0 1   ; false
[15] return   0     ; false

0.0 should be less then 0.000001

@rurban rurban reopened this Jul 18, 2013
@bartolsthoorn
Copy link
Author

I pinpointed the error, it was not about types but about the VM, weird!

potion -B -e '(60000000000 / 2) string print'
# (30000000000)
potion -X -e '(60000000000 / 2) string print'
# (2082712576)

Flags source code

Since -X is default, this difference was messing with my results. Is this a bug? Note: I'm not using your p2 branch, just this potion branch.

@rurban
Copy link
Member

rurban commented Jul 18, 2013

Yes, jit does not check for int overflow. It does this on purpose, but I want to fix it.
Esp. with JIT it should be faster to check the CPU overflow flag.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants