Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Floating point arithmetic.

Reply
Thread Tools

Floating point arithmetic.

 
 
Amit Bhatia
Guest
Posts: n/a
 
      07-11-2004
Hi there.
I am cross posting this on comp.lang.c as well: sorry for same.
The problem I am facing is as follows:
For example:
double a= 0.15;
double b=2.4;
const double VERYTINY =1.e-10;
I know b/a = 16 and hence the remainder is zero; but I am not
able to find any suitable thing to encode it into in c.
for example (fmod(b,a)>VERYTINY) returns true!
Now for this particular instance, (fmodf(b,a)>VERYTINY)
does return false.
But now if
a=0.15;
b=4.5;
then fmodf and fmod both don't help...

any suggestions on this?
I was pointed to a reference on floating point arithmetic, where they talk
of ulps etc, but is there a small function or fix to deal with this problem
available somewhere?

thanks,
amit.
 
Reply With Quote
 
 
 
 
Robbie Hatley
Guest
Posts: n/a
 
      07-11-2004

"Amit Bhatia" <(E-Mail Removed)> wrote:

> The problem I am facing is as follows:
> For example:


Example of what? It makes more sense to state the
thing you want to give an example of, before giving
examples of it.

> double a= 0.15;
> double b=2.4;
> const double VERYTINY =1.e-10;
> I know b/a = 16 and hence the remainder is zero;
> but I am not able to find any suitable thing to
> encode it into in c.


Define "encode".

Define "it".

If you want to code b/a in C, the code is:

b/a

> for example


Example of what? Please give some clue as to the thing
you're trying to give an example OF, before giving
examples!

> (fmod(b,a)>VERYTINY) returns true!


It returns false on my system. However, it seems to me
you're pushing the granularity of type double to the max.
Even if you WERE off by one part per 1e10, so what?
That's one part per ten billion. Who cares?

But if you really DO care, try acquiring a compiler that
supports type "long double". Or, perhaps, use a computer
with a 64-bit processor and compiler that defines "double"
to be 64 bits. Even if 4 or so of those bits were used
for sign and exponent, you'd still have a granularity of
about 1 part per quintillion (1e1. More precision than
you'll EVER need.

> Now for this particular instance, (fmodf(b,a)>VERYTINY)
> does return false.


What is fmodf? That's not a part of the C or C++ std.
libraries. I don't have it on my compiler (DJGPP) either.

> But now if
> a=0.15;
> b=4.5;
> then fmodf and fmod both don't help...


I get b/a = 30 and (fmod(b,a)>VERYTINY) = false.

What do YOU get?

> any suggestions on this?


Suggestions on what, precisely?

> I was pointed to a reference on floating point
> arithmetic, where they talk of ulps etc,


What's "ulps"?

> is there a small function or fix to deal with this problem
> available somewhere?


What problem are you trying to fix?

--
Cheers,
Robbie Hatley
Tustin, CA, USA
http://www.velocityreviews.com/forums/(E-Mail Removed)
http://home.pacbell.net/earnur/



 
Reply With Quote
 
 
 
 
John Harrison
Guest
Posts: n/a
 
      07-11-2004
On Sun, 11 Jul 2004 01:17:09 -0700, Robbie Hatley <lonewolfintj at pacbell
dot net> wrote:

>
>> I was pointed to a reference on floating point
>> arithmetic, where they talk of ulps etc,

>
> What's "ulps"?
>


ULP stands for unit in the last place. Its a measure of rounding error and
a common enough term in floating point arithmetic.

john
 
Reply With Quote
 
John Harrison
Guest
Posts: n/a
 
      07-11-2004
On Sat, 10 Jul 2004 23:08:01 -0500, Amit Bhatia <(E-Mail Removed)> wrote:

> Hi there.
> I am cross posting this on comp.lang.c as well: sorry for same.
> The problem I am facing is as follows:
> For example:
> double a= 0.15;
> double b=2.4;
> const double VERYTINY =1.e-10;
> I know b/a = 16 and hence the remainder is zero; but I am not
> able to find any suitable thing to encode it into in c.
> for example (fmod(b,a)>VERYTINY) returns true!
> Now for this particular instance, (fmodf(b,a)>VERYTINY)
> does return false.
> But now if
> a=0.15;
> b=4.5;
> then fmodf and fmod both don't help...
>
> any suggestions on this?


Maybe use a bigger value for VERYTINY.
Maybe use integral or rational aritmetic.
Maybe use fixed point arithmetic.

> I was pointed to a reference on floating point arithmetic, where they
> talk
> of ulps etc, but is there a small function or fix to deal with this
> problem
> available somewhere?


There is not easy answer to the problem of floating point rounding errors.
The simplest thing is not to write code that depends on any particular
exactness of floating point arithmetic. Obviously this is not always
possible but it is possible more often than people think.

So the asnwer to your question really depends on what kind of problem you
are actually trying to solve.

john
 
Reply With Quote
 
David Harmon
Guest
Posts: n/a
 
      07-11-2004
On Sat, 10 Jul 2004 23:08:01 -0500 in comp.lang.c++, Amit Bhatia
<(E-Mail Removed)> wrote,
>Hi there.
> I am cross posting this on comp.lang.c as well: sorry for same.


In fact you did so a few days ago and got some good tips.

>The problem I am facing is as follows:
> For example:
> double a= 0.15;
> double b=2.4;
> const double VERYTINY =1.e-10;


b = two and two fifths. Fifths can not be represented exactly in base
two floating point format, so this number cannot be stored exactly.
a is 16 times that, so of course has a similar approximation.

And so on. Never expect any form of exactitude from any floating point
operation, and your life will be less frustrating.

>I know b/a = 16 and hence the remainder is zero; but I am not
>able to find any suitable thing to encode it into in c.


It may be close to zero, or it may be just less than 0.15.

If you persist in this folly then I guess you need to test for both
possibilities.


 
Reply With Quote
 
Subhash
Guest
Posts: n/a
 
      07-11-2004
Amit Bhatia <(E-Mail Removed)> wrote in message news:<ccqf0m$lfj$(E-Mail Removed)>...
> Hi there.
> I am cross posting this on comp.lang.c as well: sorry for same.
> The problem I am facing is as follows:
> For example:
> double a= 0.15;
> double b=2.4;
> const double VERYTINY =1.e-10;
> I know b/a = 16 and hence the remainder is zero; but I am not
> able to find any suitable thing to encode it into in c.
> for example (fmod(b,a)>VERYTINY) returns true!
> Now for this particular instance, (fmodf(b,a)>VERYTINY)
> does return false.
> But now if
> a=0.15;
> b=4.5;
> then fmodf and fmod both don't help...
>
> any suggestions on this?
> I was pointed to a reference on floating point arithmetic, where they talk
> of ulps etc, but is there a small function or fix to deal with this problem
> available somewhere?
>
> thanks,
> amit.



int main() {
double a = 0.15;
double b = 2.4;
const double VERYTINY =1.e-10;
printf("%d", (fmod(b,a) > VERYTINY));
return 0;
}

This gives me false!
 
Reply With Quote
 
Arijit
Guest
Posts: n/a
 
      07-11-2004
Amit Bhatia <(E-Mail Removed)> wrote in message news:<ccqf0m$lfj$(E-Mail Removed)>...
> Hi there.
> I am cross posting this on comp.lang.c as well: sorry for same.
> The problem I am facing is as follows:
> For example:
> double a= 0.15;
> double b=2.4;
> const double VERYTINY =1.e-10;
> I know b/a = 16 and hence the remainder is zero; but I am not
> able to find any suitable thing to encode it into in c.
> for example (fmod(b,a)>VERYTINY) returns true!
> Now for this particular instance, (fmodf(b,a)>VERYTINY)
> does return false.
> But now if
> a=0.15;
> b=4.5;
> then fmodf and fmod both don't help...
>
> any suggestions on this?
> I was pointed to a reference on floating point arithmetic, where they talk
> of ulps etc, but is there a small function or fix to deal with this problem
> available somewhere?
>
> thanks,
> amit.



Try the following loop

cout.precision(20);
cout << b << endl << a << endl;
while(b>a)
b -= a;
cout << b << endl << a << endl;

and see the value of a and b

Your problem is that the method of not comparing floating
point values but comparing their difference to a certain limit
does not work for modulo arithmetic. The reason is simple.

Assume x(mod y) = 0
That is, x = yp

In your case, x and y are floating point values,
while p is an integer. Since p is an integer, you
can say x is divisible by y.

But a computer cannot store floating point numbers exactly.
so a floating point number x is actually stored as (x+dx)
or as (x-dx). In your case, 4.5 can be exactly stored, but
neither can 2.4 or 0.15 . Now consider what happens when you
divide (x+dx) or (x-dx) by y. (x,y,p > 0)

(x+dx)(mod y) = dx
This is ok, your comparison will work in this case, as your
VERYTINY is > dx

However, (x-dx)(mod y) = (yp-dx)(mod y)
= (y(p-1) + y - dx)(mod y) = y-dx
This y-dx is definitely mmuch greater than your VERYTINY
and therefore you do not get the desired result.

I'll give you an example with integers.

Consider dividing 57 by 19. 57(mod 19) = 0
58(mod 19) = 1 ( x+dx case)
56(mod 19) = 18 (x-dx case)

So you should write
( fmod(b,a)<VERYTINY || (a-fmod(b,a))<VERYTINY )

-Arijit
 
Reply With Quote
 
Miguel
Guest
Posts: n/a
 
      07-11-2004

When using floating-point, usually we don't test for equality, instead do
the kind of test you do (fmod(b, a) > VERYTINY)...
But if we take a look at the case in particular, the test doesn't fail on my
machine, and I suspect the > VERYTINY doesn't fail in yours, except for
negative numbers. That is,

2.4 can only be finitely represented in binary as 2.3999... that is
10.0110011(0011)
0.15 as 0.14(9) (or 0.00100110011(0011))

in my machine, perhaps yours too, fmod(2.4, 0.15) is exactly 0. This is not
surprising if we examine the mantissa bits of both numbers, they are equal.

but 4.5 does have a finite binary representation as 100.1

but fmod(4.5, 0.15) is only 1.66533e-16, and so is smaller than 1e-10... and
I don't know why the test should fail....
Since the case of the denominator being represented exactly implies that a
multiple is represented exactly too

So, given best possible representations of the input values the test
(abs(fmod(b, a)) < VERYTINY)) should work.

One exception arises when input values are themselves approximations, and,
in particular, the dividend is slightly less than it would take to be an
exact multiple. In that case, the remainder will be less than, but very
close to the denominator. So, we must test the result also against it being
very close to the denominator.

So, the full test, that should work for all cases would be (assuming we want
to know about approximate multiples):

(abs(fmod(b,a)) < VERYTINY) || (abs(fmod(b,a) - a) < VERYTINY)

Now, the value you choose for VERYTINY, depends on the application and how
many operations you have done on the input values. Of course, because the
result of fmod is in absolute value always less than a, if you know your
inputs are positive numbers, you can drop both abs function calls.


Miguel Ramos


 
Reply With Quote
 
Miguel
Guest
Posts: n/a
 
      07-11-2004

> What is fmodf? That's not a part of the C or C++ std.
> libraries. I don't have it on my compiler (DJGPP) either.


actually fmodf does exist, it is part of the C99 standard, and most modern
compilers have it.
but I think we shouldn't be very harsh, it's obvious he meant modf.


 
Reply With Quote
 
Robbie Hatley
Guest
Posts: n/a
 
      07-12-2004

"Miguel" <(E-Mail Removed)> wrote in message news:40f18fd8$0$20879$(E-Mail Removed)...
>
> > What is fmodf? That's not a part of the C or C++ std.
> > libraries. I don't have it on my compiler (DJGPP) either.

>
> actually fmodf does exist, it is part of the C99 standard,


"fmodf" is a not a keyword in C or C++, nor is it
a part of their standard libraries, according to my
reading. I found reference to "fmodf" in the
documentation for my compiler (DJGPP), where it is
listed as a "non-ANSI extention to fmod". So unless
fmodf has been added to the standard libraries very
recently, it's not standard.

> and most modern compilers have it.


Most compilers have lots of added non-ANSI functions.
Useful, but not standard.

> it's obvious he meant modf.


Probably.

--
Cheers,
Robbie Hatley
Tustin, CA, USA
(E-Mail Removed)
http://home.pacbell.net/earnur/


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Share-Point-2010 ,Share-Point -2010 Training , Share-point-2010Hyderabad , Share-point-2010 Institute Saraswati lakki ASP .Net 0 01-06-2012 06:39 AM
floating point problem... floating indeed :( teeshift Ruby 2 12-01-2006 01:16 AM
converting floating point to fixed point H aka N VHDL 15 03-02-2006 02:26 PM
floating point to fixed point conversion riya1012@gmail.com C Programming 4 02-22-2006 05:56 PM
Fixed-point format for floating-point numbers Motaz Saad Java 7 11-05-2005 05:33 PM



Advertisments