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

Incorrect Result in 32 Bit Platforms #80

Closed
nmingotti opened this issue Nov 22, 2017 · 4 comments
Closed

Incorrect Result in 32 Bit Platforms #80

nmingotti opened this issue Nov 22, 2017 · 4 comments
Labels

Comments

@nmingotti
Copy link

nmingotti commented Nov 22, 2017

Hi, write you here a snipped illustrating a wrong result I am getting. Specs of the two platform used to see the bug are below.

========================
require 'bigdecimal'
BigDecimal.limit(1000)

# ok => 2.718...
n = 1_000_000_000;
((BigDecimal.new(n) + BigDecimal.new(1)) / BigDecimal.new(n))**BigDecimal.new(n)

# gives infinity, not good, it should converge to value E or rise
# an exception if it can't compute it.
n = 1_000_000_000_0;
((BigDecimal.new(n) + BigDecimal.new(1)) / BigDecimal.new(n))**BigDecimal.new(n)
========================

The two 32 platforms in which I can see the bug are
1] ------ in a VMWare Linux Machine Runnning in OSX Host ----------------
$> irb -v
irb 0.9.6(09/06/30)
$> ruby -v
ruby 2.4.2p198 (2017-09-14 revision 59899) [i686-linux]
$> file which ruby
/usr/local/bin/ruby: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=4155341292883d00fd56de2c46abb3f23151c640, not stripped
$> uname -a
Linux foo 3.16.0-4-686-pae #1 SMP Debian 3.16.43-2+deb8u5 (2017-09-19) i686 GNU/Linux
$> cat /etc/debian_version
8.9
2] ----- In a BeagleBone Black -----------------
#> uname -a
Linux bbtest 4.4.91-ti-r133 #1 SMP Tue Oct 10 05:18:08 UTC 2017 armv7l GNU/Linux
#> cat /etc/debian_version
9.2
#> cat /etc/dogtag
BeagleBoard.org Debian Image 2017-10-10
#> ruby -v
ruby 2.3.3p222 (2016-11-21) [arm-linux-gnueabihf]
#> irb -v
irb 0.9.6(09/06/30)
#> file /usr/bin/ruby2.3
/usr/bin/ruby2.3: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 3.2.0, BuildID[sha1]=755336ae6067230d52c894c8d91ec82f6402d3ab, stripped

@mrkn
Copy link
Member

mrkn commented Nov 27, 2017

Thank you for your report. I'll check and fix it asap.

@mrkn
Copy link
Member

mrkn commented Dec 13, 2017

@nmingotti
This is a limitation of the current implementation of bigdecimal.
The reason why the result of the latter case is Infinity is that bigdecimal just returns Infinity for a positive integral exponent whose internal type is T_BIGNUM.
In 32-bit platforms, sizeof(long) is 4, so BigDecimal#** just returns Infinity because 1_000_000_000_0 is internally a bignum.

I want to and have a plan to remove this limitation, but it isn't scheduled yet.

The corresponding code location is here:
https://github.com/ruby/bigdecimal/blob/master/ext/bigdecimal/bigdecimal.c#L2507-L2516

@nmingotti
Copy link
Author

@mrkn ok, thank for checking out !
In the meanwhile, If it is possible and not to tedious to implement, could you rise an exception when the exponent goes out of the supported range ?
This would be useful, getting Infinity as final result is confusing.

@mrkn mrkn reopened this Dec 14, 2017
@mrkn mrkn closed this as completed Dec 14, 2017
@mrkn
Copy link
Member

mrkn commented Dec 14, 2017

@nmingotti Setting the exception mode, you can get FloatDomainError in that cases:

[2] pry(main)> BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, true)
=> 1
[3] pry(main)> n = 1_000_000_000_0
=> 10000000000
[4] pry(main)> BigDecimal(2) ** n
FloatDomainError: Computation results to 'Infinity'
from (pry):4:in `**'
[5] pry(main)>

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

No branches or pull requests

2 participants