Rounding floats

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

Rounding floats

timrowledge
I know that it’s a hard thing to deal with floating point numbers around the fiddly edges, but are we really unable to do a decent job of rounding floats to reasonable numbers of decimal places? This can’t be a rare thing to need to do.

For example, I’m reading temperature values for various places from the openweathermap.org site and many of them are specified to 2dp, which seems a bit optimistic for a weather site. But if I try, for example
292.37 roundTo: 0.1
I get the very unhelpful 292.40000…00003 (with too many 0s to count by eye). I understand that one option is to use formatted printing of the number but that doesn’t seem practical for this usage right now.


So, numerics aficionados, can we do any better than the sensible seeming but unsuccessful code in Number>>roundTo: ?

tim
--
tim Rowledge; [hidden email]; http://www.rowledge.org/tim
Ubi dubium ibi libertas


Reply | Threaded
Open this post in threaded view
|

Re: Rounding floats

Nicolas Cellier
Hi Tim,
you can't round float that easily, they are not multiple of 1/5.
But you can round their printed decimal representation.
That's fair because this is what you want: print the damn float

292.37 printShowingMaxDecimalPlaces: 1


Technically, 2924*0.1 and 2924/10.0 differ.
The second one is guaranteed to be the closest float to (2924/10) because there's only one inexact operation involved (the division).
The first one, not so, it's 2924 * (1/10.0), two inexact operations
Remember, 1/10 = 0.1 is false...
That's why roundTo: is failing: it uses the second formula.

Otherwise, of course, you would use ScaledDecimals or Fractions...

239.37 roundTo: 0.1s.
(239.37 roundTo: 1/10) asFloat.

But you want to print rounded, so just print rounded, don't bother with round.

2016-07-19 1:20 GMT+02:00 tim Rowledge <[hidden email]>:
I know that it’s a hard thing to deal with floating point numbers around the fiddly edges, but are we really unable to do a decent job of rounding floats to reasonable numbers of decimal places? This can’t be a rare thing to need to do.

For example, I’m reading temperature values for various places from the openweathermap.org site and many of them are specified to 2dp, which seems a bit optimistic for a weather site. But if I try, for example
292.37 roundTo: 0.1
I get the very unhelpful 292.40000…00003 (with too many 0s to count by eye). I understand that one option is to use formatted printing of the number but that doesn’t seem practical for this usage right now.


So, numerics aficionados, can we do any better than the sensible seeming but unsuccessful code in Number>>roundTo: ?

tim
--
tim Rowledge; [hidden email]; http://www.rowledge.org/tim
Ubi dubium ibi libertas





cbc
Reply | Threaded
Open this post in threaded view
|

Re: Rounding floats

cbc

On Mon, Jul 18, 2016 at 5:26 PM, Nicolas Cellier <[hidden email]> wrote:
Hi Tim,
you can't round float that easily, they are not multiple of 1/5.
But you can round their printed decimal representation.
That's fair because this is what you want: print the damn float

292.37 printShowingMaxDecimalPlaces: 1


Technically, 2924*0.1 and 2924/10.0 differ.
The second one is guaranteed to be the closest float to (2924/10) because there's only one inexact operation involved (the division).
The first one, not so, it's 2924 * (1/10.0), two inexact operations
Remember, 1/10 = 0.1 is false...
That's why roundTo: is failing: it uses the second formula.

Otherwise, of course, you would use ScaledDecimals or Fractions...

239.37 roundTo: 0.1s.
(239.37 roundTo: 1/10) asFloat.

But you want to print rounded, so just print rounded, don't bother with round.

or FixedDecimals (if you want to load that package). 
    239.37 asFixedDecimal: 1 "==> 239.4 "

2016-07-19 1:20 GMT+02:00 tim Rowledge <[hidden email]>:
I know that it’s a hard thing to deal with floating point numbers around the fiddly edges, but are we really unable to do a decent job of rounding floats to reasonable numbers of decimal places? This can’t be a rare thing to need to do.

For example, I’m reading temperature values for various places from the openweathermap.org site and many of them are specified to 2dp, which seems a bit optimistic for a weather site. But if I try, for example
292.37 roundTo: 0.1
I get the very unhelpful 292.40000…00003 (with too many 0s to count by eye). I understand that one option is to use formatted printing of the number but that doesn’t seem practical for this usage right now.


So, numerics aficionados, can we do any better than the sensible seeming but unsuccessful code in Number>>roundTo: ?

tim
--
tim Rowledge; [hidden email]; http://www.rowledge.org/tim
Ubi dubium ibi libertas









Reply | Threaded
Open this post in threaded view
|

Re: Rounding floats

timrowledge
In reply to this post by Nicolas Cellier

> On 18-07-2016, at 5:26 PM, Nicolas Cellier <[hidden email]> wrote:
>
> Hi Tim,
> you can't round float that easily, they are not multiple of ⅕.

I know - damn those awkward temperature readings!

> But you can round their printed decimal representation.
> That's fair because this is what you want: print the damn float

Unfortunately that isn’t something I can do in this case. (I think, anyway) since the numeric value will get passed around and possibly displayed somewhere else. Now of course one could argue that the place where it gets displayed should do any formatting but since the displaying morph has no idea about any rounding, limits, scaling etc of the value it might have to display…

>
> On 19-07-2016, at 7:46 AM, Chris Cunningham <[hidden email]> wrote:
>
> or FixedDecimals (if you want to load that package).
>     239.37 asFixedDecimal: 1 "==> 239.4 "

Hunh. FixedDecimals, eh? Hadn’t heard of that one before. I wonder if it’ll be friendly?

Did we ever do decimal floats? I know a lot of the work on that as a general question was done by an old IBM colleague (Mike Cowlishaw, generally a very nice chap despite that fact that he claims responsibility for IBM dropping Smalltalk in favour of java) but I had the impression it was a pretty tricky thing.

tim
--
tim Rowledge; [hidden email]; http://www.rowledge.org/tim
ASCII to  ASCII, DOS to DOS.



Reply | Threaded
Open this post in threaded view
|

Re: Rounding floats

Peter Crowther-2
On 19 July 2016 at 18:43, tim Rowledge <[hidden email]> wrote:
[...]
the displaying morph has no idea about any rounding, limits, scaling etc of the value it might have to display…

Therein lies the problem, I fear.  There's a reason for models and views...

Cheers,

- Peter


Reply | Threaded
Open this post in threaded view
|

Re: Rounding floats

timrowledge

> On 19-07-2016, at 1:35 PM, Peter Crowther <[hidden email]> wrote:
>
> On 19 July 2016 at 18:43, tim Rowledge <[hidden email]> wrote:
> [...]
> the displaying morph has no idea about any rounding, limits, scaling etc of the value it might have to display…
>
> Therein lies the problem, I fear.  There's a reason for models and views…

The problem is that a general purpose ‘display a string’ morph can’t know enough to display a string representing a number to any special format, and so has to rely upon the number value being ‘reasonable’. Which is of course a bit of a problem since numbers are well known for being unreliable jerks with bad manners.

tim
--
tim Rowledge; [hidden email]; http://www.rowledge.org/tim
Strange OpCodes: MII: Mask all Interrupts and then Interrupt



Reply | Threaded
Open this post in threaded view
|

Re: Rounding floats

Peter Crowther-2
On 20 July 2016 at 19:47, tim Rowledge <[hidden email]> wrote:

> On 19-07-2016, at 1:35 PM, Peter Crowther <[hidden email]> wrote:
>
> On 19 July 2016 at 18:43, tim Rowledge <[hidden email]> wrote:
> [...]
> the displaying morph has no idea about any rounding, limits, scaling etc of the value it might have to display…
>
> Therein lies the problem, I fear.  There's a reason for models and views…

The problem is that a general purpose ‘display a string’ morph can’t know enough to display a string representing a number to any special format, and so has to rely upon the number value being ‘reasonable’. Which is of course a bit of a problem since numbers are well known for being unreliable jerks with bad manners.

Quite.  The interesting architectural question is then where to put the cat-herder ("development manager") that converts between really useful data from unreliable jerks with bad manners (call these "developers" or "managers" as you prefer) and easy-to-consume data in an expected format for those on the other side (call these ditto).

I'm presently dealing with a large legacy* desktop stats application that's traditionally done all its rounding in the stats functions and handed ready-formatted strings to the output template system for printing.  We're migrating to an approach where the stats functions are exposed to new consumers that expect numeric data, so the rounding and formatting needs to be described by the output template and the template processing system needs to be extended to cope.  I feel your pain!

Cheers,

- Peter

P.S. Strange opcode back atcha: BEA - Bitwise Exclusive-And.

* Started in Fortran 20+ years ago, went to mixed Fortran, x86 assembler and Visual Basic, now all in C# - interesting how times change!