# C語言解釋 - 單精確度跟雙精確度
###### tags: `c`, `single precision`, `double precision`
```clike=
#include <stdio.h>
#include <stdlib.h>
int main() {
double a, b;
scanf("%f %f", &a, &b);
printf("a: %f", a);
printf("b: %f", b);
}
```
開編譯器選項,會對格式不對提出警告,不過還是會產生執行檔。
```clike=
src/test_main.c:6:18: warning: format specifies type 'float *' but the argument has type 'double *' [-Wformat]
scanf("%f %f", &a, &b);
~~ ^~
%lf
src/test_main.c:6:22: warning: format specifies type 'float *' but the argument has type 'double *' [-Wformat]
scanf("%f %f", &a, &b);
~~ ^~
%lf
src/test_main.c:10:17: warning: more '%' conversions than data arguments [-Wformat-insufficient-args]
printf("a+b: %f, a+b");
```
一樣用lldb觀察a, b
```clike=
(lldb) r
Process 1208 launched: '/Users/ewnlm/Work/Clang/KenHW/bin/test_main' (arm64)
1.54
1.581
Process 1208 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #0: 0x0000000100003f34 test_main`main at test_main.c:8:19
5 double a, b;
6 scanf("%f %f", &a, &b);
7
-> 8 printf("a: %f", a);
9 printf("b: %f", b);
10 printf("a+b: %f, a+b");
11
Target 0: (test_main) stopped.
(lldb) frame variable a b
(double) a = 2.650588257955044E-314
(double) b = 2.6507581834348151E-314
(lldb) frame variable &a &b
(double *) &a = 0x000000016fdfeab8
(double *) &b = 0x000000016fdfeab0
(lldb) x/8 0x000000016fdfeab0
0x16fdfeab0: 0x3fca5e35 0x00000001 0x3fc51eb8 0x00000001
0x16fdfeac0: 0x6fdfec10 0x00000001 0x0001108c 0x00000001
(lldb) po a
2.650588257955044E-314
```
輸入1.54, 1.581 兩個值,看第17,18行,實際存進去變成$2.65*10^{-314}$ 一個非常小的值。
```clike=
(lldb) r
Process 1281 launched: '/Users/ewnlm/Work/Clang/KenHW/bin/test_main' (arm64)
1.54
1.581
Process 1281 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #0: 0x0000000100003f20 test_main`main at test_main.c:8:20
5 double a, b;
6 scanf("%lf %lf", &a, &b);
7
-> 8 printf("a: %lf", a);
9 printf("b: %lf", b);
10 printf("a+b: %lf", a+b);
11
Target 0: (test_main) stopped.
(lldb) frame variable a b
(double) a = 1.54
(double) b = 1.581
(lldb) frame variable &a &b
(double *) &a = 0x000000016fdfeab8
(double *) &b = 0x000000016fdfeab0
(lldb) x/8 0x000000016fdfeab0
0x16fdfeab0: 0xa7ef9db2 0x3ff94bc6 0x0a3d70a4 0x3ff8a3d7
0x16fdfeac0: 0x6fdfec10 0x00000001 0x0001108c 0x00000001
```
把scanf()要掃瞄的格式換成正確的`%lf`. 再看一下a, b 變數的內容;
第17,18行,這次就是正確1.54與1.581. 就這是為什麼會看到 0 的原因。