J
James Kuyper
Dik said:Because the return of roundto(6.12345e+50, 4) should be 6.12300e+50.
I think the OP was talking about the number of digits after the decimal
point in %f format, not in %e format.
Dik said:Because the return of roundto(6.12345e+50, 4) should be 6.12300e+50.
jacob said:In lcc-win wasn't missing since it is in stdlib.h
jacob said:Dik said:Now, are we really such a C "heads" that we can't answer the OP
question IN HIS terms?
You discarded the solution of James Kuyper out of hand. Did you even
think about that solution?
double roundto(double d, int digits) {double roundto(double d,int digits);
char number[digits+10];
sprintf(number, "%.*e", (digits > 0 ? digits - 1 : 0), d);
sscanf(number, "%f", &d);
return d;
}
Or somesuch.
But that is just using my function internally within
printf!
double roundto(double d, int digits) {
char number[digits+10];
sprintf(number, "%.*e", (digits > 0 ? digits - 1 : 0), d);
sscanf(number, "%f", &d);
return d;
}
Or somesuch.
< it is surely not the best solution.jacob said:And there are others that do not give ANY solution, limiting
themselves to say why the solutions presented in some cases not
asked for would not work
I used the original solution and fixed it for double precision,
But instead of proposing a better solution this people limit
to talking nonsense without ever proposing anything else.
Then I get angry start getting mad at heathfield and this
degrades.
Richard said:jacob navia said:
.... snip ...
Show me 0.33 rounded to one decimal place.
jacob said:Mark McIntyre wrote:
.... snip ...
Yes, because stdlib.h is missing. You need it for the prototype
of atof. You saw the warning and then you spread nonsense, like
all your posts.
Hunh? How about:
double r = 0.33, s;
s = (int)((r * 10.0) + 0.5) / 10.0;
which, according to me, gives the desired value in s within the
accuracy limits of doubles.
I copy-pasted this exact code, and compiled under gcc 4.1.2:
thelinux clc_tests $ ./a.out 0.33
1374389535.0000000000000000000: 0 decimals 1374389535.0000000000000000
1374389535.0000000000000000000: 1 decimals 1374389535.0000000000000000
I'm giving this one a 'strange' score of 'high'
You are saying in essence that 1/10 is not representable in
binary.
Congratulations.
I know that.
But we are speaking about
FLOATING POINT here, that as everyone knows is an approximation
to the reals, and never anything else!
Of course there are unrepresentable numbers. Does that mean
that we can't use floating point or what?
Obviously we can't get any 100% correct representation of
all numbers in floating point, like for instance in base
ten with 1/3!
So what?
If I go to primary school and say to some kid:
Look round me 0.345345345 to 7 places he will tell
me 0.3453453, even if it is obvious that there is a
repeating fraction.
You CUT at some point, as accurately as possible and that was it!
Yes.
The existence of unrepresentable numbers in floating point
does not mean we can't use floating point
or round numbers as we wish.
It means that all our results will be ALWAYS incorrect
from the mathematically true result by some epsilon
that should be as small as possible.
It is what he asked for.
In the original message
there is no mention of 100% accuracy or of any accuracy requirements
in the first place.
I insist that
1) Given the nature of floating point numbers any solution will
be an approximation in most cases.
2) We can get the best approximation for double precision by
using more precision internally and then rounding at the
last moment.
3) The function proposed is maybe not the best, but it works
for all values in range.
jacob said:I do not know which "C" you are talking about. I am talking about
the C as defined by the C99 standard which says in the
Annex F (normative)
<quote>
The C floating types match the IEC 60559 formats as follows:
— The float type matches the IEC 60559 single format.
— The double type matches the IEC 60559 double format.
<end quote>
That is a quite clearly defined format, defined by IEEE
in 1987 with another name (IEEE754) then generalized to
IEC 60559. This is a 64 bits/53 mantissa etc.
Of course the standard is not a guide for you? Or you are still speaking
about the obsolete 1980 standard?
Which C you are referring to ?
jacob said:Besides, as you know perfectly well, most printfs are
written in C, and they do the same I am doing there
basically.
Jacob, this certainly isn't the first time you've been told that IEC
60559 is not a required part of the Standard. I've told you myself
before.
Until now, I had considered that while you generate a lot of noise and
are stubborn, you were willing to learn when you saw that you were
wrong. It turns out I was mistaken.
This is most disappointing.
Richard said:Mark McIntyre said:
Thanks, Mark, for doing that. I used the exact same code, except that I
read ahead in the thread and added <stdlib.h> as a result (I didn't get a
warning about atof because I had to switch off many diagnostics to get the
code to compile at all), and I also had to put braces around the last two
lines of roundto. I'm getting the following results:
me@here> ./foo 0.33
0.3300000000000000155: 0 decimals 256.0000000000000000
0.3300000000000000155: 1 decimals -21474836.0000000000000000
0.3300000000000000155: 2 decimals -20468203.0000000000000000
0.3300000000000000155: 3 decimals -1522532.0000000000000000
0.3300000000000000155: 4 decimals -83414.0000000000000000
0.3300000000000000155: 5 decimals -21322.0000000000000000
0.3300000000000000155: 6 decimals -1591.0000000000000000
0.3300000000000000155: 7 decimals -91.0000000000000000
0.3300000000000000155: 8 decimals 0.0000000000000000
0.3300000000000000155: 9 decimals -1.0000000000000000
0.3300000000000000155: 10 decimals 0.0000000000000000
0.3300000000000000155: 11 decimals 0.0000000000000000
0.3300000000000000155: 12 decimals 0.0000000000000000
0.3300000000000000155: 13 decimals 0.0000000000000000
0.3300000000000000155: 14 decimals 0.0000000000000000
Richard Heathfield wrote:
[...]I used the exact same code, except that I
read ahead in the thread and added <stdlib.h> as a result (I didn't get
a warning about atof because I had to switch off many diagnostics to get
the code to compile at all), and I also had to put braces around the
last two lines of roundto. I'm getting the following results:
me@here> ./foo 0.33
0.3300000000000000155: 0 decimals 256.0000000000000000
0.3300000000000000155: 1 decimals -21474836.0000000000000000
0.3300000000000000155: 2 decimals -20468203.0000000000000000
Have you any idea why this is happening?
I do find it ironic that Jacob insists the problem is soluble, but even
after using his rounding he /still/ uses your proposed solution of using
printf() to round on output...
I'm disappointed with the misleading results here which suggest that the
LHS has trailing cruft which the RHS doesn't, when both have such cruft.
Philip said:Richard Heathfield wrote: [snip]
I'm getting the following results:me@here> ./foo 0.33
0.3300000000000000155: 0 decimals 256.0000000000000000
0.3300000000000000155: 1 decimals -21474836.0000000000000000
0.3300000000000000155: 2 decimals -20468203.0000000000000000
0.3300000000000000155: 3 decimals -1522532.0000000000000000
0.3300000000000000155: 4 decimals -83414.0000000000000000
0.3300000000000000155: 5 decimals -21322.0000000000000000
0.3300000000000000155: 6 decimals -1591.0000000000000000
0.3300000000000000155: 7 decimals -91.0000000000000000
0.3300000000000000155: 8 decimals 0.0000000000000000
0.3300000000000000155: 9 decimals -1.0000000000000000
0.3300000000000000155: 10 decimals 0.0000000000000000
0.3300000000000000155: 11 decimals 0.0000000000000000
0.3300000000000000155: 12 decimals 0.0000000000000000
0.3300000000000000155: 13 decimals 0.0000000000000000
0.3300000000000000155: 14 decimals 0.0000000000000000
Have you any idea why this is happening? I got none of the warnings you
complained about (using -std=c99 -pedantic -W -Wall) and the results
seem to be what Jacob gets. (Of course, if he has invoked UB this means
nothing.)
I do find it ironic that Jacob insists the problem is soluble, but even
after using his rounding he /still/ uses your proposed solution of using
printf() to round on output...
pgp@medusa-s2:~/tmp$ gcc -std=c99 -pedantic -W -Wall -lm jn.c -ojn
jn.c:16: warning: unused parameter 'argc'
pgp@medusa-s2:~/tmp$ ./jn 0.33
0.3300000000000000155: 0 decimals 0.0000000000000000
0.3300000000000000155: 1 decimals 0.3000000000000000
0.3300000000000000155: 2 decimals 0.3300000000000000
0.3300000000000000155: 3 decimals 0.3300000000000000
0.3300000000000000155: 4 decimals 0.3300000000000000
0.3300000000000000155: 5 decimals 0.3300000000000000
0.3300000000000000155: 6 decimals 0.3300000000000000
0.3300000000000000155: 7 decimals 0.3300000000000000
0.3300000000000000155: 8 decimals 0.3300000000000000
0.3300000000000000155: 9 decimals 0.3300000000000000
0.3300000000000000155: 10 decimals 0.3300000000000000
0.3300000000000000155: 11 decimals 0.3300000000000000
0.3300000000000000155: 12 decimals 0.3300000000000000
0.3300000000000000155: 13 decimals 0.3300000000000000
0.3300000000000000155: 14 decimals 0.3300000000000000
I'm disappointed with the misleading results here which suggest that the
LHS has trailing cruft which the RHS doesn't, when both have such cruft.
2: As you can see, my solution works in your machine. Either RH is not
telling the truth (unlikely) or he is using some minor error in the
code to trip about.
Richard said:jacob navia said:
If your code has an error, however minor, then it is broken, in which case
I suggest you post a fixed version. The version you posted *does not work*
on my system. Quite apart from the fact that you are trying to solve an
impossible problem (the problem, remember, is that of rounding the value
of a double to a specified number of decimal places, which simply can't be
done), you are trying to solve it in a way that produces bizarrely
incorrect results on at least one system.
And no, I didn't make those results up.
jacob navia said:Since you provide no information on which compilation options
you used, no information on which system you are running, this
can't be solved really.
And if I have a minor error somewhere correct it instead
of just spreading FUD
Since you provide no information on which compilation options
you used, no information on which system you are running, this
can't be solved really.
And if I have a minor error somewhere correct it instead
of just spreading FUD
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.