GNU bug report logs -
#13031
large numbers
Previous Next
To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 13031 in the body.
You can then email your comments to 13031 AT debbugs.gnu.org in the normal way.
Toggle the display of automated, internal messages from the tracker.
Report forwarded
to
bug-guile <at> gnu.org
:
bug#13031
; Package
guile
.
(Thu, 29 Nov 2012 17:51:02 GMT)
Full text and
rfc822 format available.
Acknowledgement sent
to
Jozef Chraplewski <jozef <at> applicake.com>
:
New bug report received and forwarded. Copy sent to
bug-guile <at> gnu.org
.
(Thu, 29 Nov 2012 17:51:03 GMT)
Full text and
rfc822 format available.
Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):
Hi,
It looks that guile returns incorrect results when it works with really big numbers.
I've found it during resolving problem 48 from Project Euler:
http://projecteuler.net/problem=48
The solution is trivial:
(define (problem-48 limit)
(define (F)
(let loop ((n 1)
(sum 0))
(if (<= n limit)
(loop (+ n 1) (+ sum (expt n n)))
sum)))
(let* ((str (number->string (F)))
(len (string-length str)))
(substring str (- len 10) len)))
(display (problem-48 1000))
(newline)
The proper answer is 9110846700 but guile returns 6457854188
I've tested solution under other scheme implementations (MIT scheme, petite and mzscheme) and it works as it should.
Does such a big numbers in guile require any special treatment or just they are not supported?
Best,
Jozef
Information forwarded
to
bug-guile <at> gnu.org
:
bug#13031
; Package
guile
.
(Thu, 29 Nov 2012 19:11:02 GMT)
Full text and
rfc822 format available.
Message #8 received at 13031 <at> debbugs.gnu.org (full text, mbox):
[Message part 1 (text/plain, inline)]
No, they are meant to be supported without any special treatment. I don't
know what is happening in your example.
On Thu, Nov 29, 2012 at 3:42 AM, Jozef Chraplewski <jozef <at> applicake.com>wrote:
> Hi,
>
> It looks that guile returns incorrect results when it works with really
> big numbers.
>
> I've found it during resolving problem 48 from Project Euler:
>
> http://projecteuler.net/problem=48
>
> The solution is trivial:
>
> (define (problem-48 limit)
> (define (F)
> (let loop ((n 1)
> (sum 0))
> (if (<= n limit)
> (loop (+ n 1) (+ sum (expt n n)))
> sum)))
>
> (let* ((str (number->string (F)))
> (len (string-length str)))
> (substring str (- len 10) len)))
>
> (display (problem-48 1000))
> (newline)
>
>
> The proper answer is 9110846700 but guile returns 6457854188
>
> I've tested solution under other scheme implementations (MIT scheme,
> petite and mzscheme) and it works as it should.
>
> Does such a big numbers in guile require any special treatment or just
> they are not supported?
>
> Best,
> Jozef
>
>
>
[Message part 2 (text/html, inline)]
Information forwarded
to
bug-guile <at> gnu.org
:
bug#13031
; Package
guile
.
(Thu, 29 Nov 2012 19:18:01 GMT)
Full text and
rfc822 format available.
Message #11 received at 13031 <at> debbugs.gnu.org (full text, mbox):
[Message part 1 (text/plain, inline)]
Hi,
Which version of guile do you use, I get the correct value for guile
2.0.5.91-de6d8
/Stefan
On Thu, Nov 29, 2012 at 9:42 AM, Jozef Chraplewski <jozef <at> applicake.com>wrote:
> Hi,
>
> It looks that guile returns incorrect results when it works with really
> big numbers.
>
> I've found it during resolving problem 48 from Project Euler:
>
> http://projecteuler.net/problem=48
>
> The solution is trivial:
>
> (define (problem-48 limit)
> (define (F)
> (let loop ((n 1)
> (sum 0))
> (if (<= n limit)
> (loop (+ n 1) (+ sum (expt n n)))
> sum)))
>
> (let* ((str (number->string (F)))
> (len (string-length str)))
> (substring str (- len 10) len)))
>
> (display (problem-48 1000))
> (newline)
>
>
> The proper answer is 9110846700 but guile returns 6457854188
>
> I've tested solution under other scheme implementations (MIT scheme,
> petite and mzscheme) and it works as it should.
>
> Does such a big numbers in guile require any special treatment or just
> they are not supported?
>
> Best,
> Jozef
>
>
>
[Message part 2 (text/html, inline)]
Information forwarded
to
bug-guile <at> gnu.org
:
bug#13031
; Package
guile
.
(Thu, 29 Nov 2012 22:14:01 GMT)
Full text and
rfc822 format available.
Message #14 received at 13031 <at> debbugs.gnu.org (full text, mbox):
Hi,
Jozef Chraplewski <jozef <at> applicake.com> skribis:
> The solution is trivial:
>
> (define (problem-48 limit)
> (define (F)
> (let loop ((n 1)
> (sum 0))
> (if (<= n limit)
> (loop (+ n 1) (+ sum (expt n n)))
> sum)))
>
> (let* ((str (number->string (F)))
> (len (string-length str)))
> (substring str (- len 10) len)))
>
> (display (problem-48 1000))
> (newline)
>
>
> The proper answer is 9110846700 but guile returns 6457854188
I also get 9110846700 with 2.0.6+ and 1.8.8+. What version do you use?
(Bigloo 3.2a returns 5842605292, though.)
Ludo’.
Information forwarded
to
bug-guile <at> gnu.org
:
bug#13031
; Package
guile
.
(Fri, 30 Nov 2012 11:57:02 GMT)
Full text and
rfc822 format available.
Message #17 received at 13031 <at> debbugs.gnu.org (full text, mbox):
Hey guys,
I use guile 2.0.6, compiled on macbook pro 7.1 osx 10.8.2
I've compiled guild via home-brew package manager.
Here is the link to brew's formula with compilation options:
https://github.com/mxcl/homebrew/blob/master/Library/Formula/guile.rb
Best,
Jozef
On Nov 29, 2012, at 11:11 PM, Ludovic Courtès <ludo <at> gnu.org> wrote:
> Hi,
>
> Jozef Chraplewski <jozef <at> applicake.com> skribis:
>
>> The solution is trivial:
>>
>> (define (problem-48 limit)
>> (define (F)
>> (let loop ((n 1)
>> (sum 0))
>> (if (<= n limit)
>> (loop (+ n 1) (+ sum (expt n n)))
>> sum)))
>>
>> (let* ((str (number->string (F)))
>> (len (string-length str)))
>> (substring str (- len 10) len)))
>>
>> (display (problem-48 1000))
>> (newline)
>>
>>
>> The proper answer is 9110846700 but guile returns 6457854188
>
> I also get 9110846700 with 2.0.6+ and 1.8.8+. What version do you use?
>
> (Bigloo 3.2a returns 5842605292, though.)
>
> Ludo’.
Information forwarded
to
bug-guile <at> gnu.org
:
bug#13031
; Package
guile
.
(Fri, 30 Nov 2012 16:30:02 GMT)
Full text and
rfc822 format available.
Message #20 received at 13031 <at> debbugs.gnu.org (full text, mbox):
Jozef Chraplewski <jozef <at> applicake.com> skribis:
> I use guile 2.0.6, compiled on macbook pro 7.1 osx 10.8.2
What compiler and what version of GMP is it?
Thanks,
Ludo’.
Information forwarded
to
bug-guile <at> gnu.org
:
bug#13031
; Package
guile
.
(Fri, 30 Nov 2012 17:37:01 GMT)
Full text and
rfc822 format available.
Message #23 received at 13031 <at> debbugs.gnu.org (full text, mbox):
Jozef Chraplewski <jozef <at> applicake.com> writes:
> I use guile 2.0.6, compiled on macbook pro 7.1 osx 10.8.2
>
> I've compiled guild via home-brew package manager.
Could you please run "make check" in the build directory and show us the
output if any errors are reported?
Thanks!
Mark
Information forwarded
to
bug-guile <at> gnu.org
:
bug#13031
; Package
guile
.
(Sat, 01 Dec 2012 05:26:02 GMT)
Full text and
rfc822 format available.
Message #26 received at 13031 <at> debbugs.gnu.org (full text, mbox):
Hi Jozef,
Jozef Chraplewski <jozef <at> applicake.com> writes:
> It looks that guile returns incorrect results when it works with really big numbers.
Please disregard my earlier request. Can you please run the following
code and send us the output?
(let ((modulus (expt 10 10)))
(define (last10 n) (modulo n modulus))
(let loop ((n 1) (sum 0))
(if (> n 1000)
(last10 sum)
(let* ((term (expt n n))
(sum (+ sum term)))
(format #t "~4 <at> a ~10 <at> a ~10 <at> a~%" n (last10 term) (last10 sum))
(loop (+ n 1) sum)))))
Thanks,
Mark
Information forwarded
to
bug-guile <at> gnu.org
:
bug#13031
; Package
guile
.
(Mon, 03 Dec 2012 16:38:02 GMT)
Full text and
rfc822 format available.
Message #29 received at 13031 <at> debbugs.gnu.org (full text, mbox):
[Message part 1 (text/plain, inline)]
Hey guys,
Sorry for the late response, I was offline during the weekend.
@Mark, you can find output in attachment.
gcc -v
Using built-in specs.
Target: i686-apple-darwin11
Configured with: /private/var/tmp/llvmgcc42/llvmgcc42-2336.11~67/src/configure --disable-checking --enable-werror --prefix=/Applications/Xcode.app/Contents/Developer/usr/llvm-gcc-4.2 --mandir=/share/man --enable-languages=c,objc,c++,obj-c++ --program-prefix=llvm- --program-transform-name=/^[cg][^.-]*$/s/$/-4.2/ --with-slibdir=/usr/lib --build=i686-apple-darwin11 --enable-llvm=/private/var/tmp/llvmgcc42/llvmgcc42-2336.11~67/dst-llvmCore/Developer/usr/local --program-prefix=i686-apple-darwin11- --host=x86_64-apple-darwin11 --target=i686-apple-darwin11 --with-gxx-include-dir=/usr/include/c++/4.2.1
Thread model: posix
gcc version 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.11.00)
brew info gmp
gmp: stable 5.0.5
http://gmplib.org/
/usr/local/Cellar/gmp/5.0.5 (11 files, 2.3M) *
https://github.com/mxcl/homebrew/commits/master/Library/Formula/gmp.rb
==> Options
--32-bit
Build 32-bit only
Best,
Jozef
[output.txt (text/plain, attachment)]
[Message part 3 (text/plain, inline)]
On Dec 1, 2012, at 6:22 AM, Mark H Weaver <mhw <at> netris.org> wrote:
> (let ((modulus (expt 10 10)))
> (define (last10 n) (modulo n modulus))
> (let loop ((n 1) (sum 0))
> (if (> n 1000)
> (last10 sum)
> (let* ((term (expt n n))
> (sum (+ sum term)))
> (format #t "~4 <at> a ~10 <at> a ~10 <at> a~%" n (last10 term) (last10 sum))
> (loop (+ n 1) sum)))))
Information forwarded
to
bug-guile <at> gnu.org
:
bug#13031
; Package
guile
.
(Tue, 04 Dec 2012 00:17:02 GMT)
Full text and
rfc822 format available.
Message #32 received at 13031 <at> debbugs.gnu.org (full text, mbox):
[Message part 1 (text/plain, inline)]
Hi Jozef,
I guess that on your system, (* 65536 65536) evaluates to 0.
Is that right?
If so, I believe the problem is caused by an aggressive optimization in
recent versions of Clang, which breaks Guile's logic for detecting
overflow when multiplying two fixnums.
Currently, Guile computes kk = xx * yy and checks for overflow by
verifying that kk / xx == yy.
I believe that Clang is optimizing out the check, because recent C
standards permit C implementations to assume that signed integer
arithmetic will never overflow. For details, see:
http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html
One solution is to compile with the "-fwrapv" option, which should
disable the optimization.
Another solution is to apply the following patch.
Jozef, would you be willing to test this patch and tell me if it fixes
the problem?
Many thanks,
Mark
[FIXNUM_PRODUCT_OVERFLOW_FIX.patch (text/x-diff, inline)]
diff --git a/libguile/numbers.c b/libguile/numbers.c
index 52e227f..66c95db 100644
--- a/libguile/numbers.c
+++ b/libguile/numbers.c
@@ -7640,10 +7640,16 @@ scm_product (SCM x, SCM y)
if (SCM_LIKELY (SCM_I_INUMP (y)))
{
scm_t_inum yy = SCM_I_INUM (y);
- scm_t_inum kk = xx * yy;
- SCM k = SCM_I_MAKINUM (kk);
- if ((kk == SCM_I_INUM (k)) && (kk / xx == yy))
- return k;
+#if SCM_I_FIXNUM_BIT < 32 && SCM_HAVE_T_INT64
+ scm_t_int64 kk = xx * (scm_t_int64) yy;
+ if (SCM_FIXABLE (kk))
+ return SCM_I_MAKINUM (kk);
+#else
+ scm_t_inum axx = (xx > 0) ? xx : -xx;
+ scm_t_inum ayy = (yy > 0) ? yy : -yy;
+ if (SCM_MOST_POSITIVE_FIXNUM / axx >= ayy)
+ return SCM_I_MAKINUM (xx * yy);
+#endif
else
{
SCM result = scm_i_inum2big (xx);
Information forwarded
to
bug-guile <at> gnu.org
:
bug#13031
; Package
guile
.
(Wed, 05 Dec 2012 16:22:02 GMT)
Full text and
rfc822 format available.
Message #35 received at 13031 <at> debbugs.gnu.org (full text, mbox):
I wrote:
> I guess that on your system, (* 65536 65536) evaluates to 0.
> Is that right?
I should have mentioned that if you're on a 64-bit system, then it may
instead be the case that (* (expt 2 32) (expt 2 32)) evaluates to 0.
Same bug either way, and the rest of my previous email still applies.
Thanks,
Mark
> If so, I believe the problem is caused by an aggressive optimization in
> recent versions of Clang, which breaks Guile's logic for detecting
> overflow when multiplying two fixnums.
>
> Currently, Guile computes kk = xx * yy and checks for overflow by
> verifying that kk / xx == yy.
>
> I believe that Clang is optimizing out the check, because recent C
> standards permit C implementations to assume that signed integer
> arithmetic will never overflow. For details, see:
> http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html
>
> One solution is to compile with the "-fwrapv" option, which should
> disable the optimization.
>
> Another solution is to apply the following patch.
>
> Jozef, would you be willing to test this patch and tell me if it fixes
> the problem?
>
> Many thanks,
> Mark
>
>
>
> diff --git a/libguile/numbers.c b/libguile/numbers.c
> index 52e227f..66c95db 100644
> --- a/libguile/numbers.c
> +++ b/libguile/numbers.c
> @@ -7640,10 +7640,16 @@ scm_product (SCM x, SCM y)
> if (SCM_LIKELY (SCM_I_INUMP (y)))
> {
> scm_t_inum yy = SCM_I_INUM (y);
> - scm_t_inum kk = xx * yy;
> - SCM k = SCM_I_MAKINUM (kk);
> - if ((kk == SCM_I_INUM (k)) && (kk / xx == yy))
> - return k;
> +#if SCM_I_FIXNUM_BIT < 32 && SCM_HAVE_T_INT64
> + scm_t_int64 kk = xx * (scm_t_int64) yy;
> + if (SCM_FIXABLE (kk))
> + return SCM_I_MAKINUM (kk);
> +#else
> + scm_t_inum axx = (xx > 0) ? xx : -xx;
> + scm_t_inum ayy = (yy > 0) ? yy : -yy;
> + if (SCM_MOST_POSITIVE_FIXNUM / axx >= ayy)
> + return SCM_I_MAKINUM (xx * yy);
> +#endif
> else
> {
> SCM result = scm_i_inum2big (xx);
Information forwarded
to
bug-guile <at> gnu.org
:
bug#13031
; Package
guile
.
(Fri, 07 Dec 2012 10:41:01 GMT)
Full text and
rfc822 format available.
Message #38 received at 13031 <at> debbugs.gnu.org (full text, mbox):
Hey Mark,
Yes, I use 64-bit machine and (* (expt 2 32) (expt 2 32)) produces 0 (without the patch).
I've applied your fix and it works perfectly.
I suppose that you will add the patch to the next stable version (2.0.8 ??)
Thanks for help and great work!
Best,
Jozef
On Dec 5, 2012, at 5:20 PM, Mark H Weaver <mhw <at> netris.org> wrote:
> I wrote:
>> I guess that on your system, (* 65536 65536) evaluates to 0.
>> Is that right?
>
> I should have mentioned that if you're on a 64-bit system, then it may
> instead be the case that (* (expt 2 32) (expt 2 32)) evaluates to 0.
> Same bug either way, and the rest of my previous email still applies.
>
> Thanks,
> Mark
>
>
>> If so, I believe the problem is caused by an aggressive optimization in
>> recent versions of Clang, which breaks Guile's logic for detecting
>> overflow when multiplying two fixnums.
>>
>> Currently, Guile computes kk = xx * yy and checks for overflow by
>> verifying that kk / xx == yy.
>>
>> I believe that Clang is optimizing out the check, because recent C
>> standards permit C implementations to assume that signed integer
>> arithmetic will never overflow. For details, see:
>> http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html
>>
>> One solution is to compile with the "-fwrapv" option, which should
>> disable the optimization.
>>
>> Another solution is to apply the following patch.
>>
>> Jozef, would you be willing to test this patch and tell me if it fixes
>> the problem?
>>
>> Many thanks,
>> Mark
>>
>>
>>
>> diff --git a/libguile/numbers.c b/libguile/numbers.c
>> index 52e227f..66c95db 100644
>> --- a/libguile/numbers.c
>> +++ b/libguile/numbers.c
>> @@ -7640,10 +7640,16 @@ scm_product (SCM x, SCM y)
>> if (SCM_LIKELY (SCM_I_INUMP (y)))
>> {
>> scm_t_inum yy = SCM_I_INUM (y);
>> - scm_t_inum kk = xx * yy;
>> - SCM k = SCM_I_MAKINUM (kk);
>> - if ((kk == SCM_I_INUM (k)) && (kk / xx == yy))
>> - return k;
>> +#if SCM_I_FIXNUM_BIT < 32 && SCM_HAVE_T_INT64
>> + scm_t_int64 kk = xx * (scm_t_int64) yy;
>> + if (SCM_FIXABLE (kk))
>> + return SCM_I_MAKINUM (kk);
>> +#else
>> + scm_t_inum axx = (xx > 0) ? xx : -xx;
>> + scm_t_inum ayy = (yy > 0) ? yy : -yy;
>> + if (SCM_MOST_POSITIVE_FIXNUM / axx >= ayy)
>> + return SCM_I_MAKINUM (xx * yy);
>> +#endif
>> else
>> {
>> SCM result = scm_i_inum2big (xx);
Reply sent
to
Mark H Weaver <mhw <at> netris.org>
:
You have taken responsibility.
(Fri, 07 Dec 2012 17:08:01 GMT)
Full text and
rfc822 format available.
Notification sent
to
Jozef Chraplewski <jozef <at> applicake.com>
:
bug acknowledged by developer.
(Fri, 07 Dec 2012 17:08:02 GMT)
Full text and
rfc822 format available.
Message #43 received at 13031-done <at> debbugs.gnu.org (full text, mbox):
Hi Jozef,
Jozef Chraplewski <jozef <at> applicake.com> writes:
> Yes, I use 64-bit machine and (* (expt 2 32) (expt 2 32)) produces 0 (without the patch).
>
> I've applied your fix and it works perfectly.
Excellent! Thanks for bringing this problem to our attention,
and for helping us track it down :)
> I suppose that you will add the patch to the next stable version (2.0.8 ??)
Yes.
Thanks again,
Mark
bug archived.
Request was from
Debbugs Internal Request <help-debbugs <at> gnu.org>
to
internal_control <at> debbugs.gnu.org
.
(Sat, 05 Jan 2013 12:24:03 GMT)
Full text and
rfc822 format available.
This bug report was last modified 12 years and 163 days ago.
Previous Next
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.