The output format and contents of the%f in the "Go" printf format string

Source: Internet
Author: User
Original address: http://blog.sina.com.cn/s/blog_605f5b4f0100x3ep.html

First declare: compiling printf under VC ++ will not automatically do type conversion, such as int a = 3; printf ("% f", a); error will be reported during operation, runtime error R6002: floating point not loaded. The following are the procedures in Linux.

 

The following is borrowed from others to help analyze the cause.

 

Output an integer in decimal format:

int a = 0, b = 0;
printf ("% f,% d", a, b);
However, the operation result is not satisfactory. The% f field outputs 0, and the% d field outputs a larger data.

 

Because I just read the memory representation of floating point numbers recently, the explanation of the above code is as follows:
% f is a double type, which requires two bytes (reproduced correction: double data type occupies 8 bytes, int is 4 bytes, so two int types are required), so printf encounters% f That is, read the two integer data of a and b. When the output of% d is needed, only the next unit of b can be read. Naturally, it is not the expected data.

 

Own comment:

The printf in this is executed in a sequential manner. First find% f, read 8 bytes, there is no element in the value queue, and% d reads the next byte.

 

However, a friend said that% f is a float type, and% lf is a double type. I deliberately consulted the MSDN and Linux man manuals and found no such descriptions. In the linux man manual,% lf is a long double type.

 

Own comment:

There seems to be no difference between lf and f.


To illustrate the problem, I did several experiments:

 

Experiment one, checking% f requires reading several bytes

int a = 0, b = 0, c = 5;
printf ("% f,% d \ n", a, b, c);
Output results:
0,5
Conclusion:% f reads 8 bytes, which is the size of two integers

 

Own comment:

Personally, I think that the author of this article changed the compiler by executing this code. This printf is executed in reverse order according to the stack. First read% d, pop c = 5, then read% f, pop b and a.

 

Experiment two, checking% lf requires reading several bytes

int a = 0, b = 0, c = 5;
printf ("% lf,% d \ n", a, b, c);
Output results:
0,5
Conclusion:% lf also reads 8 bytes (maybe it's related to the machine bit width, I'm a 32-bit machine)

Own comment:

Ibid. This printf is executed in the reverse order of the stack, first reading% d, popping c = 5, then reading% lf, popping b and a.

 

Experiment three, check printf to read float type data

float a = 0.0f;
int b = 5;
printf ("% f,% d \ n", a, b);
Output results:
0.0,5
Conclusion: The float type occupies only 4 bytes of data, but the previous experiment 1 has proved that% f will read 8 bytes, which is the width of the double type. Therefore, the compiler converts the float type parameter into the stack beforehand Become double.

 

Own comment:

Ibid. This printf is executed in the reverse order of the stack, first reading% d, popping b = 5, then reading% f, popping a and the next 4 bytes, why it is 0.0 is explained later.

 

Experiment 4 proves the conclusion of Experiment 3 again

float a = 0.0f;
int b = 5;
printf ("% d,% d,% d \ n", a, b);
Output results:
0,0,5
Conclusion: a is 8 bytes when it is pushed onto the stack.

 

Own comment:

Ibid. This printf is executed in the reverse order of the stack, first reading% d, popping b = 5, then reading% d, popping a part of 4 bytes, then reading% d, popping 4 bytes after a, as for Why it is 0.0 is explained later.

 

 

Own experiment:

Because the compiler used is different, the results are also different. The following is my own experiment and result analysis, g ++ under Linux. Since the compiler used uses different printf output, the above is reverse order, and mine is positive order.

 

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

int main ()
{
    int a = 10, b = 20, c = 5;
   
    printf ("a:% d \ n", a);
    printf ("b:% d \ n", b);
    printf ("c:% d \ n", c);
result:
a: 10
b: 20
c: 5
Analysis: the output format corresponds to the value format, no problem

    printf ("a:% f \ n", a);
    printf ("b:% f \ n", b);
    printf ("c:% f \ n", c);
result:
a: 0.000000
b: 0.000000
c: 0.000000
Analysis: The output format does not correspond to the value format. The output of% f for all ints is 0; it can be seen from the analysis below that this is due to the mismatch between the types of% f and int.

    printf ("a:% f, b:% d \ n", a, b);
    printf ("a:% f, b:% d, other:% d \ n", a, b);
    printf ("a:% f, b:% d \ n", a, b, c);
    printf ("a:% f, b:% d, c:% f \ n", a, b, c);
    printf ("a:% f, b:% d, c:% d \ n", a, b, c);
Results:
a: 0.000000, b: 10
a: 0.000000, b: 10, other: 20
a: 0.000000, b: 10
a: 0.000000, b: 10, c: 0.000000
a: 0.000000, b: 10, c: 20
Analysis: printf ("a:% f, b:% d \ n", a, b); and the results a: 0.000000, b: 10 can see that the order of the compiler is like this:
 The compiler executes sequentially. First execute% f without corresponding type, the result is 0.000000. Execute% d, the corresponding first int type is a = 10, and the result is 10.
 Same as above, when printf ("a:% f, b:% d, other:% d \ n", a, b) is executed, when the second% d is output, it corresponds to the second int type b = 20.
 Same as above, when printf ("a:% f, b:% d \ n", a, b, c) is executed,% d execution is not used for a = 10, neither b nor c
 As above, when printf ("a:% f, b:% d, c:% f \ n", a, b, c) is executed,% d is executed for a = 10, and the subsequent% f has no corresponding type, and c is not used;
 As above, when printf ("a:% f, b:% d, c:% d \ n", a, b, c) is executed,% f has no correspondence, and output 0,% d% d corresponds to a and b ;

   

    float x = 10.0f;
    int y = 5;
   
    printf ("x:% d \ n", x);
    printf ("y:% d \ n", y);
result:
x: 4196537
y: 5
Analysis: printf ("x:% d \ n", x) outputs x: 4196537. You can see that if the number of bytes of the value> the number of bytes to be output, a part of the value bytes is intercepted and output.

 

    printf ("x:% f \ n", x);
    printf ("y:% f \ n", y);
result:
x: 10.000000
y: 10.000000
Analysis: printf ("y:% f \ n", y); The output y is 10f is something that surprised me. Because c = 5 has been defined at the beginning and printf ("c:% f \ n", c) has a result of 0 and a value of y of 5.
From c, if int is output as% f due to type mismatch, it is specified that% f outputs 0;
From the perspective of y, if int is output as% f, it seems that y and the four bytes before or after y are output as a float or double as% f.
Or from the point of view of c, if the output of int according to% f is also 8 bytes, but it is very unfortunate that all a, b, and c are output as 8 bytes.

the fact is:
The combination of the two,% f and y types do not match.% F reads 8 bytes from y for output, and the float value of these 8 bytes is exactly 10f (from the conclusion below)
And printf ("c:% f \ n", c) is the value of 8 bytes after c

 

    printf ("x:% d, y:% d \ n", x, y);
    printf ("x:% d, y:% f \ n", x, y);
    printf ("x:% f, y:% d \ n", x, y);
    printf ("x:% f, y:% f \ n", x, y);
    printf ("x1:% d, x2:% d, y:% d \ n", x, y);
    printf ("x1:% f, x2:% d, y:% d \ n", x, y);
Results:
x: 5, y: 476096928
x: 5, y: 10.000000
x: 10.000000, y: 5
x: 10.000000, y: 0.000000
x1: 5, x2: 476096928, y: 476092288
x1: 10.000000, x2: 5, y: 476096928
analysis:

printf ("x:% d, y:% d \ n", x, y) printf is executed in order, x does not match% d, find the next parameter value y, and one matches% d, so it outputs 5, And then% d, because there is no parameter value, find the next 4 bytes of y and output as int 476096928


printf ("x:% d, y:% f \ n", x, y) Here printf is executed in order, x does not match% d, finds the next parameter value y, matches% d, so it outputs 5, and After the% f, read the next 8 bytes of output, you can see that the output of% f is 10f, which is the same as that of% f alone output y.

printf ("x:% f, y:% d \ n", x, y) type matching, normal output


printf ("x:% f, y:% f \ n", x, y)% f matches x and outputs 10f, while% f and y do not match. Reading 8 bytes after y outputs, but this The time is actually 0f? Began to suspect that the address of y output 10f is the address of x? Do you suspect that all% f ints are 0? ?


printf ("x1:% d, x2:% d, y:% d \ n", x, y); matches% d with y = 5, then% d and% d are 4 after reading y Bytes then output 476096928 and 476092288
printf ("x1:% f, x2:% d, y:% d \ n", x, y); After x and y match,% d has to read a 4-byte output after y. 476096928

 

You can see that when% d outputs 4 bytes after y, (1) the first time is 476096928, (5) the second time is 476096928 and 476092288 (6) the third time is 476096928


    return 0;
}

[Go] Output format and content of% f in printf format string
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.