Confused about Floats on 64-bit Pharo 6

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
14 messages Options
Reply | Threaded
Open this post in threaded view
|

Confused about Floats on 64-bit Pharo 6

Sven Van Caekenberghe-2
I am working in Pharo 6 RC, 64-bit on macOS 10.12.5

One of the tests of STON fails, #testFloat and I got confused about Floats on 64-bit Pharo 6.

Is there a write-up that explains the new/changed situation ?

Because, what I see is the following:

Float pi.
1.3.

Both the above give me SmallFloat64 instances.

(10 raisedTo: 100) asFloat.
1.0e100.
10.0 raisedTo: 100.

All 3 above give me BoxedFloat64 instance.
But the first 2 give wrong results (correct answer is 1.0e100) !

(10 raisedTo: 100) asFloat.
 "5.15323791002091e91"

1.0e100.
 "5.15323791002091e91"

Why ?

BoxedFloat64 allInstances.
SmallFloat64 allInstances.

The first is not-empty, the second is (logical since these are immediate values).
I thought BoxedFloat64 should not be used in 64-bit ?

Also, should #emin, #emax and friends not be different for SmallFloat64 ?

Sven
Reply | Threaded
Open this post in threaded view
|

Re: Confused about Floats on 64-bit Pharo 6

Nicolas Cellier
Hi Sven,
SmallFloat64 consumes 3bits taken from exponent for tagging immediate value.
So very small values and very large values don't fit in SmallFloat64 and require a BoxedFloat64.

I don't think we should change emin and emax though.
The reason is that emin and emax are public methods for accessing the underlying floating point model.
Small/Boxed Float are implementation details, they both implement the same float model with different levels of optimization.

For the rest of the report, it's a bug we will have to track catch and fix ASAP

2017-06-01 14:53 GMT+02:00 Sven Van Caekenberghe <[hidden email]>:
I am working in Pharo 6 RC, 64-bit on macOS 10.12.5

One of the tests of STON fails, #testFloat and I got confused about Floats on 64-bit Pharo 6.

Is there a write-up that explains the new/changed situation ?

Because, what I see is the following:

Float pi.
1.3.

Both the above give me SmallFloat64 instances.

(10 raisedTo: 100) asFloat.
1.0e100.
10.0 raisedTo: 100.

All 3 above give me BoxedFloat64 instance.
But the first 2 give wrong results (correct answer is 1.0e100) !

(10 raisedTo: 100) asFloat.
 "5.15323791002091e91"

1.0e100.
 "5.15323791002091e91"

Why ?

BoxedFloat64 allInstances.
SmallFloat64 allInstances.

The first is not-empty, the second is (logical since these are immediate values).
I thought BoxedFloat64 should not be used in 64-bit ?

Also, should #emin, #emax and friends not be different for SmallFloat64 ?

Sven

Reply | Threaded
Open this post in threaded view
|

Re: Confused about Floats on 64-bit Pharo 6

Nicolas Cellier


2017-06-01 15:29 GMT+02:00 Nicolas Cellier <[hidden email]>:
Hi Sven,
SmallFloat64 consumes 3bits taken from exponent for tagging immediate value.
So very small values and very large values don't fit in SmallFloat64 and require a BoxedFloat64.

I don't think we should change emin and emax though.
The reason is that emin and emax are public methods for accessing the underlying floating point model.
Small/Boxed Float are implementation details, they both implement the same float model with different levels of optimization.

For the rest of the report, it's a bug we will have to track catch and fix ASAP

(is looks like a shift of 1 bit)
 
2017-06-01 14:53 GMT+02:00 Sven Van Caekenberghe <[hidden email]>:
I am working in Pharo 6 RC, 64-bit on macOS 10.12.5

One of the tests of STON fails, #testFloat and I got confused about Floats on 64-bit Pharo 6.

Is there a write-up that explains the new/changed situation ?

Because, what I see is the following:

Float pi.
1.3.

Both the above give me SmallFloat64 instances.

(10 raisedTo: 100) asFloat.
1.0e100.
10.0 raisedTo: 100.

All 3 above give me BoxedFloat64 instance.
But the first 2 give wrong results (correct answer is 1.0e100) !

(10 raisedTo: 100) asFloat.
 "5.15323791002091e91"

1.0e100.
 "5.15323791002091e91"

Why ?

BoxedFloat64 allInstances.
SmallFloat64 allInstances.

The first is not-empty, the second is (logical since these are immediate values).
I thought BoxedFloat64 should not be used in 64-bit ?

Also, should #emin, #emax and friends not be different for SmallFloat64 ?

Sven


Reply | Threaded
Open this post in threaded view
|

Re: Confused about Floats on 64-bit Pharo 6

Nicolas Cellier
Can't reproduce in Squeak trunk 64bits with latest opensmalltalk-VM,
So for me it should'nt be a VM problem, (or it's fixed already).

2017-06-01 15:31 GMT+02:00 Nicolas Cellier <[hidden email]>:


2017-06-01 15:29 GMT+02:00 Nicolas Cellier <[hidden email]>:
Hi Sven,
SmallFloat64 consumes 3bits taken from exponent for tagging immediate value.
So very small values and very large values don't fit in SmallFloat64 and require a BoxedFloat64.

I don't think we should change emin and emax though.
The reason is that emin and emax are public methods for accessing the underlying floating point model.
Small/Boxed Float are implementation details, they both implement the same float model with different levels of optimization.

For the rest of the report, it's a bug we will have to track catch and fix ASAP

(is looks like a shift of 1 bit)
 
2017-06-01 14:53 GMT+02:00 Sven Van Caekenberghe <[hidden email]>:
I am working in Pharo 6 RC, 64-bit on macOS 10.12.5

One of the tests of STON fails, #testFloat and I got confused about Floats on 64-bit Pharo 6.

Is there a write-up that explains the new/changed situation ?

Because, what I see is the following:

Float pi.
1.3.

Both the above give me SmallFloat64 instances.

(10 raisedTo: 100) asFloat.
1.0e100.
10.0 raisedTo: 100.

All 3 above give me BoxedFloat64 instance.
But the first 2 give wrong results (correct answer is 1.0e100) !

(10 raisedTo: 100) asFloat.
 "5.15323791002091e91"

1.0e100.
 "5.15323791002091e91"

Why ?

BoxedFloat64 allInstances.
SmallFloat64 allInstances.

The first is not-empty, the second is (logical since these are immediate values).
I thought BoxedFloat64 should not be used in 64-bit ?

Also, should #emin, #emax and friends not be different for SmallFloat64 ?

Sven



Reply | Threaded
Open this post in threaded view
|

Re: Confused about Floats on 64-bit Pharo 6

Sven Van Caekenberghe-2
In reply to this post by Nicolas Cellier

> On 1 Jun 2017, at 15:29, Nicolas Cellier <[hidden email]> wrote:
>
> Hi Sven,
> SmallFloat64 consumes 3bits taken from exponent for tagging immediate value.
> So very small values and very large values don't fit in SmallFloat64 and require a BoxedFloat64.
>
> I don't think we should change emin and emax though.
> The reason is that emin and emax are public methods for accessing the underlying floating point model.
> Small/Boxed Float are implementation details, they both implement the same float model with different levels of optimization.

If I am on 64-bit and SmallFloat64 is used (the default, right ?), then I have a smaller exponent range (right ?), so I should be able to access meta info about the currently applying limits, no ?

I recently added that to NeoJSON to protect against overly large/small exponents when reading floats, like 1e1231231231.

I understand about this being an implementation detail, but if the choice of implementation changes the range, it seems important to be able to know this, one way or another.

> For the rest of the report, it's a bug we will have to track catch and fix ASAP

Thanks!

> 2017-06-01 14:53 GMT+02:00 Sven Van Caekenberghe <[hidden email]>:
> I am working in Pharo 6 RC, 64-bit on macOS 10.12.5
>
> One of the tests of STON fails, #testFloat and I got confused about Floats on 64-bit Pharo 6.
>
> Is there a write-up that explains the new/changed situation ?
>
> Because, what I see is the following:
>
> Float pi.
> 1.3.
>
> Both the above give me SmallFloat64 instances.
>
> (10 raisedTo: 100) asFloat.
> 1.0e100.
> 10.0 raisedTo: 100.
>
> All 3 above give me BoxedFloat64 instance.
> But the first 2 give wrong results (correct answer is 1.0e100) !
>
> (10 raisedTo: 100) asFloat.
>  "5.15323791002091e91"
>
> 1.0e100.
>  "5.15323791002091e91"
>
> Why ?
>
> BoxedFloat64 allInstances.
> SmallFloat64 allInstances.
>
> The first is not-empty, the second is (logical since these are immediate values).
> I thought BoxedFloat64 should not be used in 64-bit ?
>
> Also, should #emin, #emax and friends not be different for SmallFloat64 ?
>
> Sven
>


Reply | Threaded
Open this post in threaded view
|

Re: Confused about Floats on 64-bit Pharo 6

Nicolas Cellier


2017-06-01 15:37 GMT+02:00 Sven Van Caekenberghe <[hidden email]>:

> On 1 Jun 2017, at 15:29, Nicolas Cellier <[hidden email]> wrote:
>
> Hi Sven,
> SmallFloat64 consumes 3bits taken from exponent for tagging immediate value.
> So very small values and very large values don't fit in SmallFloat64 and require a BoxedFloat64.
>
> I don't think we should change emin and emax though.
> The reason is that emin and emax are public methods for accessing the underlying floating point model.
> Small/Boxed Float are implementation details, they both implement the same float model with different levels of optimization.

If I am on 64-bit and SmallFloat64 is used (the default, right ?), then I have a smaller exponent range (right ?), so I should be able to access meta info about the currently applying limits, no ?

Yes and no.
Yes if you care about implementation details.
No if you delegate to abstract class Float, ignore the details and let the VM entirely deal with those.

My opinion is that most applications should not care of those details and should avoid duplicating the VM job.
Except maybe very optimized or low level libraries (Fuel?)
 

I recently added that to NeoJSON to protect against overly large/small exponents when reading floats, like 1e1231231231.
 
Good thing! This should be backported to number parsers,

 

I understand about this being an implementation detail, but if the choice of implementation changes the range, it seems important to be able to know this, one way or another.


It does not change the range of the underlying abstract Float model.
If those meta-data are really needed, you must find another accessor than emin and emax or you will break the model.

(2.0 timesTwoPower: Float emax // 8 + 1) is a BoxedFloat64. It's predecessor is Small.
I let you find the ones near emin by yourself.

> For the rest of the report, it's a bug we will have to track catch and fix ASAP

Thanks!

> 2017-06-01 14:53 GMT+02:00 Sven Van Caekenberghe <[hidden email]>:
> I am working in Pharo 6 RC, 64-bit on macOS 10.12.5
>
> One of the tests of STON fails, #testFloat and I got confused about Floats on 64-bit Pharo 6.
>
> Is there a write-up that explains the new/changed situation ?
>
> Because, what I see is the following:
>
> Float pi.
> 1.3.
>
> Both the above give me SmallFloat64 instances.
>
> (10 raisedTo: 100) asFloat.
> 1.0e100.
> 10.0 raisedTo: 100.
>
> All 3 above give me BoxedFloat64 instance.
> But the first 2 give wrong results (correct answer is 1.0e100) !
>
> (10 raisedTo: 100) asFloat.
>  "5.15323791002091e91"
>
> 1.0e100.
>  "5.15323791002091e91"
>
> Why ?
>
> BoxedFloat64 allInstances.
> SmallFloat64 allInstances.
>
> The first is not-empty, the second is (logical since these are immediate values).
> I thought BoxedFloat64 should not be used in 64-bit ?
>
> Also, should #emin, #emax and friends not be different for SmallFloat64 ?
>
> Sven
>



Reply | Threaded
Open this post in threaded view
|

Re: Confused about Floats on 64-bit Pharo 6

Henrik Sperre Johansen
In reply to this post by Sven Van Caekenberghe-2
SmallInteger >> digitAt: has an n > 4 ifTrue: [^0] check, in 64bit this needs to check against 8.
(The value represents max number of 8-bit digits in a SmallInteger)

"I thought BoxedFloat64 should not be used in 64-bit ?"
It will be used for some large exponents, search for "immediate float" in https://clementbera.wordpress.com/2014/01/16/spurs-new-object-format/ 
for a good description.

"Also, should #emin, #emax and friends not be different for SmallFloat64 ? "
No, it's an implementation detail.
Both float classes represent 64bit floating points with emin/emax as listed.
When one is insufficient; it should be swapped to the other automatically, in a manner similar  to Byte/WideStrings instances.

Cheers,
Henry
Reply | Threaded
Open this post in threaded view
|

Re: Confused about Floats on 64-bit Pharo 6

Sven Van Caekenberghe-2

> On 1 Jun 2017, at 15:59, Henrik Sperre Johansen <[hidden email]> wrote:
>
> SmallInteger >> digitAt: has an n > 4 ifTrue: [^0] check, in 64bit this needs
> to check against 8.
> (The value represents max number of 8-bit digits in a SmallInteger)

I can confirm that this fixes the problems that I reported. I guess we should include this patch ?

This fixes some of the failing tests in Kernel-Tests-Numbers but not all of them (some others are really hardcoded constants in the tests).

> "I thought BoxedFloat64 should not be used in 64-bit ?"
> It will be used for some large exponents, search for "immediate float" in
> https://clementbera.wordpress.com/2014/01/16/spurs-new-object-format/ 
> for a good description.
>
> "Also, should #emin, #emax and friends not be different for SmallFloat64 ? "
> No, it's an implementation detail.
> Both float classes represent 64bit floating points with emin/emax as listed.
> When one is insufficient; it should be swapped to the other automatically,
> in a manner similar  to Byte/WideStrings instances.

OK, I understand better now.

Thank you both.

> Cheers,
> Henry
>
>
>
> --
> View this message in context: http://forum.world.st/Confused-about-Floats-on-64-bit-Pharo-6-tp4948805p4948828.html
> Sent from the Pharo Smalltalk Developers mailing list archive at Nabble.com.
>


Reply | Threaded
Open this post in threaded view
|

Re: Confused about Floats on 64-bit Pharo 6

Eliot Miranda-2
In reply to this post by Henrik Sperre Johansen
Hi Henrik, Hi Esteban, Hi Marcus,

> On Jun 1, 2017, at 6:59 AM, Henrik Sperre Johansen <[hidden email]> wrote:
>
> SmallInteger >> digitAt: has an n > 4 ifTrue: [^0] check, in 64bit this needs
> to check against 8.
> (The value represents max number of 8-bit digits in a SmallInteger)

In general you need to take a careful look at the differences between Squeak 4.6 and Squeak trunk in SmallInteger and Float to harvest all the fixes for 64-bit SmallIntegers and SmallFloat64/BoxedFloat64.

> "I thought BoxedFloat64 should not be used in 64-bit ?"
> It will be used for some large exponents, search for "immediate float" in
> https://clementbera.wordpress.com/2014/01/16/spurs-new-object-format/ 
> for a good description.
>
> "Also, should #emin, #emax and friends not be different for SmallFloat64 ? "
> No, it's an implementation detail.
> Both float classes represent 64bit floating points with emin/emax as listed.
> When one is insufficient; it should be swapped to the other automatically,
> in a manner similar  to Byte/WideStrings instances.
>
> Cheers,
> Henry

Reply | Threaded
Open this post in threaded view
|

Re: Confused about Floats on 64-bit Pharo 6

Eliot Miranda-2
In reply to this post by Henrik Sperre Johansen
Hi Henrik,

> On Jun 1, 2017, at 7:10 AM, Henrik Sperre Johansen <[hidden email]> wrote:
>
> For a solution that works without change in 32/64 migration, one could use
> self class maxVal digitLength
>
> ... but there's quite a bit of calculation in digitLength.
>
> Speaking of excessive calculation;
> SmallInteger class >> startUp: isImageStarting
>    "The image is either being newly started (isImageStarting is true), or it's
> just been snapshotted.
>     If this has just been a snapshot, skip all the startup stuff."
>    | next val |
>    isImageStarting ifFalse: [^self].
>    val := -32768. "Assume at least 16 bits"
>    [next := val + val.
>    next class == self] whileTrue:
>        [val := next].
>    minVal := val.
>    maxVal := -1 - val
>
> ... really? If this actually runs on 64bit image startup, that's quite
> impressive!

This is hardly excessive :-). It only takes 45 or 46 iterations to discover the max 64-bit integer.  The code is modeled on the Smalltalk-80 v 2 code that was on the original PARC Smalltalk tape which was there for 32-bit systems; the PARC Smalltalks were 16-bit.  Squeak, and hence Pharo, derived from Smalltalk-80 v 1 and so didn't have this code.



Cheers,
Eliot
Reply | Threaded
Open this post in threaded view
|

Re: Confused about Floats on 64-bit Pharo 6

Sven Van Caekenberghe-2
In reply to this post by Henrik Sperre Johansen

> On 1 Jun 2017, at 15:59, Henrik Sperre Johansen <[hidden email]> wrote:
>
> SmallInteger >> digitAt: has an n > 4 ifTrue: [^0] check, in 64bit this needs
> to check against 8.
> (The value represents max number of 8-bit digits in a SmallInteger)

I guess that the special case in there should also be adapted to:

self = SmallInteger minVal ifTrue:
   ["Can't negate minVal -- treat specially"
    ^ #(0 0 0 0 0 0 0 16) at: n].

Correct ?
Reply | Threaded
Open this post in threaded view
|

Re: Confused about Floats on 64-bit Pharo 6

Sven Van Caekenberghe-2
In reply to this post by Sven Van Caekenberghe-2

> On 1 Jun 2017, at 16:28, Sven Van Caekenberghe <[hidden email]> wrote:
>
> I can confirm that this fixes the problems that I reported. I guess we should include this patch ?

I'll try to make an issue and patch later tonight

> This fixes some of the failing tests in Kernel-Tests-Numbers but not all of them (some others are really hardcoded constants in the tests).

I think that I can fix most tests by adding some #wordSize tests
Reply | Threaded
Open this post in threaded view
|

Re: Confused about Floats on 64-bit Pharo 6

Sven Van Caekenberghe-2

> On 1 Jun 2017, at 17:20, Sven Van Caekenberghe <[hidden email]> wrote:
>
>
>> On 1 Jun 2017, at 16:28, Sven Van Caekenberghe <[hidden email]> wrote:
>>
>> I can confirm that this fixes the problems that I reported. I guess we should include this patch ?
>
> I'll try to make an issue and patch later tonight

https://pharo.fogbugz.com/f/cases/20102/SmallInteger-digitAt-not-ready-for-64-bit-Some-Kernel-Tests-Numbers-fail-to-take-64-bit-into-account

Needs a good review

>> This fixes some of the failing tests in Kernel-Tests-Numbers but not all of them (some others are really hardcoded constants in the tests).
>
> I think that I can fix most tests by adding some #wordSize tests


Reply | Threaded
Open this post in threaded view
|

Re: Confused about Floats on 64-bit Pharo 6

Stephane Ducasse-3
Tx you all for taking care about this. 


On Thu, Jun 1, 2017 at 10:03 PM, Sven Van Caekenberghe <[hidden email]> wrote:

> On 1 Jun 2017, at 17:20, Sven Van Caekenberghe <[hidden email]> wrote:
>
>
>> On 1 Jun 2017, at 16:28, Sven Van Caekenberghe <[hidden email]> wrote:
>>
>> I can confirm that this fixes the problems that I reported. I guess we should include this patch ?
>
> I'll try to make an issue and patch later tonight

https://pharo.fogbugz.com/f/cases/20102/SmallInteger-digitAt-not-ready-for-64-bit-Some-Kernel-Tests-Numbers-fail-to-take-64-bit-into-account

Needs a good review

>> This fixes some of the failing tests in Kernel-Tests-Numbers but not all of them (some others are really hardcoded constants in the tests).
>
> I think that I can fix most tests by adding some #wordSize tests