This code, compiled with visual studio .NET 2003,
double a = 95.022, b = 0.01;
printf ("%lf - floor(%lf / %lf) * %lf = %.17lf\n", a, a, b, b, a -
floor(a / b) * b);
a = 95.021, b = 0.01;
printf ("%lf - floor(%lf / %lf) * %lf = %.17lf\n", a, a, b, b, a -
floor(a / b) * b);
a = 95.020, b = 0.01;
printf ("%lf - floor(%lf / %lf) * %lf = %.17lf\n", a, a, b, b, a -
floor(a / b) * b);
a = 95.022, b = 0.01;
printf ("fmod(%lf, %lf) = %.17lf\n", a, b, fmod(a, b));
a = 95.021, b = 0.01;
printf ("fmod(%lf, %lf) = %.17lf\n", a, b, fmod(a, b));
a = 95.020, b = 0.01;
printf ("fmod(%lf, %lf) = %.17lf\n", a, b, fmod(a, b));
generates this output:
95.022000 - floor(95.022000 / 0.010000) * 0.010000 =
0.0020000000000 0955
95.021000 - floor(95.021000 / 0.010000) * 0.010000 =
0.0010000000000 0477
95.020000 - floor(95.020000 / 0.010000) * 0.010000 =
0.0000000000000 0000
fmod(95.022000, 0.010000) = 0.0020000000000 0359
fmod(95.021000, 0.010000) = 0.0009999999999 9882
fmod(95.020000, 0.010000) = 0.0099999999999 9404
everything makes sense, except for the last line. why does fmod return
0.01 instead of 0.0? 17 6407 jo************@ comcast.net wrote: fmod(95.022000, 0.010000) = 0.0020000000000 0359 fmod(95.021000, 0.010000) = 0.0009999999999 9882 fmod(95.020000, 0.010000) = 0.0099999999999 9404
everything makes sense, except for the last line. why does fmod return 0.01 instead of 0.0?
I don't know.
I get similar results with my homemade fmod.
/* BEGIN new.c output */
fs_fmod(95.0220 00, 0.010000) is 0.002000
fs_fmod(95.0210 00, 0.010000) is 0.001000
fs_fmod(95.0200 00, 0.010000) is 0.010000
/* END new.c output */
/* BEGIN new.c */
#include <stdio.h>
#include <float.h>
double fs_fmod(double x, double y);
int main(void)
{
puts("/* BEGIN new.c output */\n");
printf("fs_fmod (95.022000, 0.010000) is %f\n"
, fs_fmod(95.0220 00, 0.010000));
printf("fs_fmod (95.021000, 0.010000) is %f\n"
, fs_fmod(95.0210 00, 0.010000));
printf("fs_fmod (95.020000, 0.010000) is %f\n"
, fs_fmod(95.0200 00, 0.010000));
puts("\n/* END new.c output */");
return 0;
}
double fs_fmod(double x, double y)
{
double a, b;
const double c = x;
if (0 > c) {
x = -x;
}
if (0 > y) {
y = -y;
}
if (y != 0 && DBL_MAX >= y && DBL_MAX >= x) {
while (x >= y) {
a = x / 2;
b = y;
while (a >= b) {
b *= 2;
}
x -= b;
}
} else {
x = 0;
}
return 0 > c ? -x : x;
}
/* END new.c */
--
pete jo************@ comcast.net writes: This code, compiled with visual studio .NET 2003,
double a = 95.022, b = 0.01; printf ("%lf - floor(%lf / %lf) * %lf = %.17lf\n", a, a, b, b, a - floor(a / b) * b); a = 95.021, b = 0.01; printf ("%lf - floor(%lf / %lf) * %lf = %.17lf\n", a, a, b, b, a - floor(a / b) * b); a = 95.020, b = 0.01; printf ("%lf - floor(%lf / %lf) * %lf = %.17lf\n", a, a, b, b, a - floor(a / b) * b);
a = 95.022, b = 0.01; printf ("fmod(%lf, %lf) = %.17lf\n", a, b, fmod(a, b)); a = 95.021, b = 0.01; printf ("fmod(%lf, %lf) = %.17lf\n", a, b, fmod(a, b)); a = 95.020, b = 0.01; printf ("fmod(%lf, %lf) = %.17lf\n", a, b, fmod(a, b));
generates this output:
95.022000 - floor(95.022000 / 0.010000) * 0.010000 = 0.0020000000000 0955 95.021000 - floor(95.021000 / 0.010000) * 0.010000 = 0.0010000000000 0477 95.020000 - floor(95.020000 / 0.010000) * 0.010000 = 0.0000000000000 0000 fmod(95.022000, 0.010000) = 0.0020000000000 0359 fmod(95.021000, 0.010000) = 0.0009999999999 9882 fmod(95.020000, 0.010000) = 0.0099999999999 9404
everything makes sense, except for the last line. why does fmod return 0.01 instead of 0.0?
Because none of the literals in your program can be represented
exactly in binary floating-point.
See section 14 of the comp.lang.c FAQ, <http://www.c-faq.com/>.
--
Keith Thompson (The_Other_Keit h) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Thanks Pete.
I take it your code is based on an accepted algorithm for computing
floating-point modulus values. Assuming fmod implementations do the
same thing, or something similar, it seems strange that fmod would
return something that seems that "far off"...if the return value was
0.0000000000045 2 or something like that, fine. but something that
rounds to 0.01...strange.
Here's a defintion of fmod from http://www.opengroup.org/onlinepubs/.../xsh/fmod.html
The fmod() function returns the value x - i * y for some integer i such
that, if y is non-zero, the result has the same sign as x and magnitude
less than the magnitude of y.
strictly speaking, 0.00999999... is a valid return value since it's
less than 0.01...I haven't cranked through the computation, but maybe
if i went up by one, then the result is less than zero, and it can't
return a negative value for these operands, so somehow you're left with
0.00999999...
calc.exe gets it right <g>
<jo************ @comcast.net> wrote in message
news:11******** *************@z 14g2000cwz.goog legroups.com... This code, compiled with visual studio .NET 2003,
double a = 95.022, b = 0.01; printf ("%lf - floor(%lf / %lf) * %lf = %.17lf\n", a, a, b, b, a - floor(a / b) * b); a = 95.021, b = 0.01; printf ("%lf - floor(%lf / %lf) * %lf = %.17lf\n", a, a, b, b, a - floor(a / b) * b); a = 95.020, b = 0.01; printf ("%lf - floor(%lf / %lf) * %lf = %.17lf\n", a, a, b, b, a - floor(a / b) * b);
a = 95.022, b = 0.01; printf ("fmod(%lf, %lf) = %.17lf\n", a, b, fmod(a, b)); a = 95.021, b = 0.01; printf ("fmod(%lf, %lf) = %.17lf\n", a, b, fmod(a, b)); a = 95.020, b = 0.01; printf ("fmod(%lf, %lf) = %.17lf\n", a, b, fmod(a, b));
generates this output:
95.022000 - floor(95.022000 / 0.010000) * 0.010000 = 0.0020000000000 0955 95.021000 - floor(95.021000 / 0.010000) * 0.010000 = 0.0010000000000 0477 95.020000 - floor(95.020000 / 0.010000) * 0.010000 = 0.0000000000000 0000 fmod(95.022000, 0.010000) = 0.0020000000000 0359 fmod(95.021000, 0.010000) = 0.0009999999999 9882 fmod(95.020000, 0.010000) = 0.0099999999999 9404
everything makes sense, except for the last line. why does fmod return 0.01 instead of 0.0?
First of all, it doesn't return 0.01. According to you, it returns
0.0099999999999 9404 which is "close to" 0.01, but is NOT 0.01.
The roundoff /truncation error encountered is thus 0.0000000000000 0596
Note that the first line is off by a similar amount, the only difference
being that the roundoff/truncation ended up slightly larger than the "exact"
answer rather than slightly smaller.
See comments others have made about the computer's inability to represent
0.01 exactly.
--
Fred L. Kleinschmidt
Boeing Associate Technical Fellow
Technical Architect, Software Reuse Project
There's a disconnect. I'm fully aware that 0.00999999... is the closest
the machine can get to representing 0.01 after computing the
floating-point modulo. However, that's not my question...the question
is, why does fmod(95.02, 0.01) return "something that rounds to 0.01"
(quoting myself), whether that's 0.0099999999999 9404 or
0.0100000000000 0596, when the correct decimal modulus of 95.02 and 0.01
is 0.0, and most definitely not 0.01? 95.022 % 0.01 = 0.002. 95.021 %
0.01 = 0.001. 95.020 % 0.01 = 0.000, unless you're using fmod, which
returns something that rounds to 0.01...there's no way that much
difference is due only to limitations on binary floating-point
representation (or implicit type promotions).
In other words, if fmod(95.02, 0.01) returned -0.0000000000000 0404, or
0.0000000000000 0596, I wouldn't have posted.
calc.exe returns 0 for 95.02 mod 0.01, not 0.01. I'd guess that's
because calc.exe uses BCD. It still looks like fmod has an unexpected
boundary condition when x % y ~ 0. jo************@ comcast.net wrote:
<snip code> everything makes sense, except for the last line. why does fmod return 0.01 instead of 0.0?
Keeping Keith Thompson's reply in mind, experiment with the
program below. And while you're at it, take a look at the link.
/* a method for computing the single precision
binary representation of a decimal fraction */
/* see: http://www.nuvisionmiami.com/books/a...oating_tut.htm */
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int pow2, mant_bit;
long double minuend, subtrahend, remainder, decfrac;
char mantissa[24];
if(argc != 2 || argv[1][0] != '.')
{
printf("usage: >pgm_name <decimal fraction>\n");
exit(EXIT_FAILU RE);
}
decfrac = 0.0;
minuend = strtold(argv[1], NULL);
printf("\n\tsta rting: %.12Lf\n\n", minuend);
for(pow2=2, mant_bit=0; mant_bit<23; pow2*=2, mant_bit++)
{
printf("%d", mant_bit + 1);
subtrahend = 1.0 / pow2;
if(minuend - subtrahend == 0.0)
{
printf("\tsubtr acting %.12Lf\n", subtrahend);
remainder = minuend - subtrahend;
minuend = remainder;
printf("\tremai nder = %.12Lf\n", remainder);
mantissa[mant_bit] = '1';
decfrac += subtrahend;
continue;
}
else if(minuend - subtrahend > 0.0)
{
printf("\tsubtr acting %.12Lf\n", subtrahend);
remainder = minuend - subtrahend;
minuend = remainder;
printf("\tremai nder = %.12Lf\n", remainder);
mantissa[mant_bit] = '1';
decfrac += subtrahend;
}
else
{
mantissa[mant_bit] = '0';
printf("\n");
}
}
mantissa[mant_bit] = '\0';
printf("\n\tbin ary mantissa: .%s\n", mantissa);
printf("\tdecim al fraction: %.12Lf\n", decfrac);
return 0;
} jo************@ comcast.net wrote: There's a disconnect.
A disconnect with what? (See below).
Brian
--
Please quote enough of the previous message for context. To do so from
Google, click "show options" and use the Reply shown in the expanded
header.
On 2006-02-14, jo************@ comcast.net <jo************ @comcast.net> wrote: There's a disconnect. I'm fully aware that 0.00999999... is the closest the machine can get to representing 0.01 after computing the floating-point modulo. However, that's not my question...the question is, why does fmod(95.02, 0.01) return "something that rounds to 0.01" (quoting myself), whether that's 0.0099999999999 9404 or 0.0100000000000 0596, when the correct decimal modulus of 95.02 and 0.01 is 0.0, and most definitely not 0.01? 95.022 % 0.01 = 0.002. 95.021 %
printf("%a == %.100f\n", 95.02, 95.02);
printf("%a == %.100f\n", .01, .01);
[cutting off excess zeros in the pasted output]
0x1.7c147ae147a e1p+6 == 95.019999999999 996020960679743 438959121704101 \
5625
0x1.47ae147ae14 7bp-7 == 0.0100000000000 000002081668171 172168513294309 \
377670288085937 5
_those_ are the numbers that fmod sees.
ah...thanks to all for straightening me out, and sorry for the
confusion. And here I thought I was smart...I was just looking at the
output, and didn't account for the fact that the inputs get adjusted
when represented in binary too. This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
by: Zunbeltz Izaola |
last post by:
Hi,
I have a problem with % operation. It returns a incorrect value in
this case:
>>> -2.77555756156e-17%1
1.0
where the returned value should be -2.77555756156e-17.
|
by: seia0106 |
last post by:
Hello,
I have a C++ program , which has following two lines of code
z=atan2(x,y);
z=(float)(fmod(2*pi+z, 2*pi);
The comments written by the other programmer says that second line is
used to extend the range of variable z from '-pi to pi' to '-2pi to
2pi'.
|
by: Lonnie Princehouse |
last post by:
I've been trying to debug this for two days now, and it's a longshot
but I'm hoping that someone here might recognize a solution. I've got
a C extension which calls a function in a C library, which calls
another function in another library, which calls another function,
which calls fmod from the standard C math library. All of these are
shared libraries on Linux (x86 Gentoo 2.6.9). In other words, the
calling looks like this:
Python...
|
by: stau |
last post by:
Hi!
I'm reading a C book, and it says that fmod() returns the remainder of the
exact division of it's arguments. Well, in a exact division, the remainder
shall always be 0 (zero), so this don't make any logic (I guess).
Anyway, foward in the chapter it says that fmod returns the remainder of
the integer division of it's arguments. I checked KnR 2nd ed. and the
man page, and still can't figure out wich one is correct.
|
by: Gintautas |
last post by:
I'm trying to play a part of wav file.
FSOUND_Sample_Load (0,"T01.wav",FSOUND_NORMAL, 0,0);
plays all file
FSOUND_Sample_Load (0,"T01.wav",FSOUND_NORMAL, 0,90000);
plays file until 90000 sample
FSOUND_Sample_Load (0,"T01.wav",FSOUND_NORMAL, 25000, 25000);
dont't play anything
any suggestions?
| |
by: Aaron Gray |
last post by:
Does anyone have a good fmod() function written in Javascript ?
Many thanks in advance,
Aaron
|
by: bummerland |
last post by:
Hi,
I have a problem with the function fmod.
Why is fmod(5.7, 0.1) = 0.1 ?? Why is it not 0?
tia bummerland
|
by: bsabiston |
last post by:
Hi, I'm trying to get the fractional part of a floating point
number. I've tried fmod() and modf(), and while both do work, they
also occasionally return 1.0 for the fractional part of the number
instead of 0.0. This is on a mac using xcode. This should not ever
happen should it?
Thanks
Bob
|
by: marktang |
last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look !
Part I. Meaning of...
|
by: jinu1996 |
last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth.
The Art of Business Website Design
Your website is...
|
by: Hystou |
last post by:
Overview:
Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
| |
by: agi2029 |
last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own....
Now, this would greatly impact the work of software developers. The idea...
|
by: conductexam |
last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one.
At the time of converting from word file to html my equations which are in the word document file was convert into image.
Globals.ThisAddIn.Application.ActiveDocument.Select();...
|
by: TSSRALBI |
last post by:
Hello
I'm a network technician in training and I need your help.
I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs.
The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols.
I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
|
by: 6302768590 |
last post by:
Hai team
i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
|
by: muto222 |
last post by:
How can i add a mobile payment intergratation into php mysql website.
|
by: bsmnconsultancy |
last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...
| |