unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
* strange behaviour of (floor .)
@ 2009-12-28 17:02 guign
  2009-12-28 19:42 ` Paul Emsley
  2010-01-03 16:17 ` Thien-Thi Nguyen
  0 siblings, 2 replies; 7+ messages in thread
From: guign @ 2009-12-28 17:02 UTC (permalink / raw)
  To: guile-user

Hej all :)

I'm a little confused by the results of (floor .) in a simple
computation to get the fractional part of a monetary value. Maybe
someone can comment on this, as especially in the last test case below
the results seem very strange to me... 

The starting point is:
guile> (rationalize (floor (* (- 12.34 (floor 12.34)) 100)) .0)
33

The actual result shoud be 34.

I tired the following simplifications:

guile> (rationalize (floor (* (- 12.34 (floor 12.34)) 100)) .0)
33
guile> (floor (* (- 12.34 (floor 12.34)) 100))
33.0
guile> (* (- 12.34 (floor 12.34)) 100)
34.0

And checked, if this might be some sort of expected behaviour:
guile> (floor 34.0)
34.0

I'm using guile 1.8.5. 

Thanks, and have a nice time :)
	Kai





^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: strange behaviour of (floor .)
  2009-12-28 17:02 strange behaviour of (floor .) guign
@ 2009-12-28 19:42 ` Paul Emsley
  2009-12-28 21:25   ` guign
  2010-01-03 16:17 ` Thien-Thi Nguyen
  1 sibling, 1 reply; 7+ messages in thread
From: Paul Emsley @ 2009-12-28 19:42 UTC (permalink / raw)
  To: guile-user

guign@mails.selgrad.org wrote:
> Hej all :)
>
> I'm a little confused by the results of (floor .) in a simple
> computation to get the fractional part of a monetary value. Maybe
> someone can comment on this, as especially in the last test case below
> the results seem very strange to me... 
>
> The starting point is:
> guile> (rationalize (floor (* (- 12.34 (floor 12.34)) 100)) .0)
> 33
>
> The actual result shoud be 34.
>
>   

That's one of the answers you will get if you use a computer to 
calculate the results.
33 is the other.

floor is working fine.

Consider the following:

(floor (* (- 12.34000000000001 (floor 12.34)) 100))
(floor (* (- 12.33999999999999 (floor 12.34)) 100))


Given that floating point number storage is not precise, different 
values is entirely reasonable.  You have to be a bit more sophisticated 
in your floor usage.


Paul.





^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: strange behaviour of (floor .)
  2009-12-28 19:42 ` Paul Emsley
@ 2009-12-28 21:25   ` guign
  0 siblings, 0 replies; 7+ messages in thread
From: guign @ 2009-12-28 21:25 UTC (permalink / raw)
  To: guile-user

Hej...

> > The actual result shoud be 34.
> That's one of the answers you will get if you use a computer to 
> calculate the results.
... what every computer scientist should know about floating point
numbers... ;)

seems like I didn't think about it, sorry :)

the number in my example is in fact not exactly represented, the
approximation is 12.33999999999999985789, and so, well... :)

thanks :)





^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: strange behaviour of (floor .)
  2009-12-28 17:02 strange behaviour of (floor .) guign
  2009-12-28 19:42 ` Paul Emsley
@ 2010-01-03 16:17 ` Thien-Thi Nguyen
  2010-01-03 17:43   ` guign
  2010-01-03 20:51   ` Keith Wright
  1 sibling, 2 replies; 7+ messages in thread
From: Thien-Thi Nguyen @ 2010-01-03 16:17 UTC (permalink / raw)
  To: guile-user

() guign@mails.selgrad.org
() Mon, 28 Dec 2009 18:02:36 +0100

   Maybe someone can comment on this

(define (cents f)
  (remainder (inexact->exact (truncate (* 100 f))) 100))

Here, `truncate' is preferred because (floor -12.34) => -13.0.

Note, however, that usually it is better (less fiddly)
to represent monetary values as integers.

thi




^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: strange behaviour of (floor .)
  2010-01-03 16:17 ` Thien-Thi Nguyen
@ 2010-01-03 17:43   ` guign
  2010-01-03 20:51   ` Keith Wright
  1 sibling, 0 replies; 7+ messages in thread
From: guign @ 2010-01-03 17:43 UTC (permalink / raw)
  To: Thien-Thi Nguyen; +Cc: guile-user

> Here, `truncate' is preferred because (floor -12.34) => -13.0.
good point :)

> Note, however, that usually it is better (less fiddly)
> to represent monetary values as integers.
yeah, I think I will use integers for such stuff in the future. my
monetary values usually don't exceed standard 32 bit integer values
anyway, even when I reserve two decimal digits for fixed point... ;)

kai.





^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: strange behaviour of (floor .)
  2010-01-03 20:51   ` Keith Wright
@ 2010-01-03 20:16     ` Linas Vepstas
  0 siblings, 0 replies; 7+ messages in thread
From: Linas Vepstas @ 2010-01-03 20:16 UTC (permalink / raw)
  To: Keith Wright; +Cc: guile-user, ttn

2010/1/3 Keith Wright <kwright@keithdiane.us>:

>
> CFO: What happened to the $12,345.67?
> You: Well, you see sir, IEEE floating point...

Heh. Common misconception.

The core problem, in accounting, is that some divisions
and multiplications are allowed, and others are not. So
for example, you are allowed to divide cost by number of
shares to obtain share price (which is generally a flt pt
number with 12 or more digits of precision). However,
multiplying the number of shares by share price to obtain
a dollar amount is forbiden, because doing so will always
lead to roundoff errors in the cost, leading to all sorts of
accounting imbalances,

Example: bought 300 shares at $12.01/share on June 1st
and bought 500 shares at $12.05/share on June 2nd. What
was the average price paid? How many decimals are needed
to correctly express this average share price? What number
does one get when one computes the average share price
times the total 800 shares bought? How does it compare to
the actual cost paid?

--linas




^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: strange behaviour of (floor .)
  2010-01-03 16:17 ` Thien-Thi Nguyen
  2010-01-03 17:43   ` guign
@ 2010-01-03 20:51   ` Keith Wright
  2010-01-03 20:16     ` Linas Vepstas
  1 sibling, 1 reply; 7+ messages in thread
From: Keith Wright @ 2010-01-03 20:51 UTC (permalink / raw)
  To: ttn; +Cc: guile-user

> From: Thien-Thi Nguyen <ttn@gnuvola.org>
>
> Note, however, that usually it is better (less fiddly)
> to represent monetary values as integers.

Yes, always represent money as an integer number
of cents and put in a decimal point when you
print.  That is, "$16.98" is produced by
something like (money->string 1698).  This
is true for ALL languages, although it is
especially easy to do in Scheme with its
large integer arithmetic.

If you will need large integers in some other
language, take the time to implement them.  You do
NOT want to lose precision by using floating
point.  "Fiddly" is the least of your worries;
you might go to jail for round-off error.

You do not want to finish this conversation:

CFO: What happened to the $12,345.67?
You: Well, you see sir, IEEE floating point...

   -- Keith




^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2010-01-03 20:51 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-12-28 17:02 strange behaviour of (floor .) guign
2009-12-28 19:42 ` Paul Emsley
2009-12-28 21:25   ` guign
2010-01-03 16:17 ` Thien-Thi Nguyen
2010-01-03 17:43   ` guign
2010-01-03 20:51   ` Keith Wright
2010-01-03 20:16     ` Linas Vepstas

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).