about float

¸

¸ßÁú

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
float j = 1.0f, i =j;
int n = 0;
for(; i - j - 1.00f; ++n, j /= 10)
{
;
}
printf("%d", n);

return EXIT_SUCCESS;
}

I supposed the output was 6, because the float's precision is 6, but
as the result, the output is 20.
why?
 
R

Richard Bos

=?GB2312?B?uN/B+g==?= said:
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
float j = 1.0f, i =j;
int n = 0;
for(; i - j - 1.00f; ++n, j /= 10)
{
;

(As an aside: why the belt _and_ braces?)
}
printf("%d", n);

return EXIT_SUCCESS;
}

I supposed the output was 6, because the float's precision is 6,

For starters, you don't know that. A float's precision is _at least_ 6
decimals. It is allowed to be more.
Second, you're not guaranteed that the computation in the for loop is
being done in the order you think it should be.

To get to the bottom of this, I'd start by printing the value you're
testing against, inside the loop.

Richard
 
R

Richard Heathfield

?? said:
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
float j = 1.0f, i =j;
int n = 0;
for(; i - j - 1.00f; ++n, j /= 10)
{
;
}
printf("%d", n);

return EXIT_SUCCESS;
}

I supposed the output was 6, because the float's precision is 6, but
as the result, the output is 20.
why?

Because i - j - 1.00f will continue to have a non-zero value for that many
iterations (on your system). Imprecision does not imply truncation. If j
is "supposed" to be, say, 0.000100000, it might actually be stored as
something like 0.0001068115234375. And 0.000001 might be stored as
something like 0.0000152587890625. Clearly, with j set to that value, 1.0
- j - 1.0 will be non-zero.
 
M

Martin Ambuhl

高龙 said:
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
float j = 1.0f, i =j;
int n = 0;
for(; i - j - 1.00f; ++n, j /= 10)
{
;
}
printf("%d", n);

return EXIT_SUCCESS;
}

I supposed the output was 6, because the float's precision is 6, but
as the result, the output is 20.
why?

Try running a version of your program like the following, and examine
your output (which will likely be different from mine). Think about
what it tells you. In particular, think about why j is never, for j < 1,
exactly ten to some negative power.

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <float.h>

int main(void)
{
float j = 1.0f, i = j;
int hexdigit, decdigit;
int n = 0;
hexdigit = (3 + CHAR_BIT * sizeof j) / 4;
decdigit = (2 + CHAR_BIT * sizeof j) * 0.301;
printf("With this implementation, sizeof(float) = %zu,\n"
"and FLT_DIG = %d. In spite of this, we will\n"
"use precisions of %d (hex) and %d (decimal).\n"
" i = %.*a (%.*g)\n\n",
sizeof(float), FLT_DIG, hexdigit, decdigit,
hexdigit, i, decdigit, i);


for (; i - j - 1.00f; ++n, j /= 10) {
printf("n = %d, j = %.*a (%.*g),\n"
" i - j - 1.f = %.*a (%.*g)\n",
n,
hexdigit, j, decdigit, j,
hexdigit, i - j - 1.f, decdigit, i - j - 1.f);
}
printf("%d\n", n); /* note the end-of-line character at
the end of the last line of output. */

return EXIT_SUCCESS;
}


With this implementation, sizeof(float) = 4,
and FLT_DIG = 6. In spite of this, we will
use precisions of 8 (hex) and 10 (decimal).
i = 0x8.00000000p-3 (1)

n = 0, j = 0x8.00000000p-3 (1),
i - j - 1.f = -0x8.00000000p-3 (-1)
n = 1, j = 0xc.ccccd000p-7 (0.1000000015),
i - j - 1.f = -0xc.cccd0000p-7 (-0.1000000238)
n = 2, j = 0xa.3d70a666p-10 (0.01000000015),
i - j - 1.f = -0xa.3d70a666p-10 (-0.01000000015)
n = 3, j = 0x8.3126e666p-13 (0.0009999999776),
i - j - 1.f = -0x8.3126e666p-13 (-0.0009999999776)
n = 4, j = 0xd.1b716666p-17 (9.999999311e-05),
i - j - 1.f = -0xd.1b716666p-17 (-9.999999311e-05)
n = 5, j = 0xa.7c5ab333p-20 (9.99999902e-06),
i - j - 1.f = -0xa.7c5ab333p-20 (-9.99999902e-06)
n = 6, j = 0x8.637bc000p-23 (9.999998838e-07),
i - j - 1.f = -0x8.637bc000p-23 (-9.999998838e-07)
n = 7, j = 0xd.6bf93333p-27 (9.999998838e-08),
i - j - 1.f = -0xd.6bf93333p-27 (-9.999998838e-08)
8
 

Ask a Question

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.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top