定點數和浮點數的細節講解

一、了解定點數和浮點數

計算機中的實數處理一般有兩種方法:定點數和浮點數。定點數指的是小數點位置固定的數值,典型的例子是貨幣的計算,小數點後兩位即為分。

浮點數指的是小數點位置可以向左或向右浮動的數值,這裡的「浮動」指的是小數點對數值精度的影響。

比如,$1.23 \times 10^4$和$12.3 \times 10^3$都可以用科學計數法表示為1.23e+04,但是前者的小數點的位置在大數的後面,而後者小數點的位置在大數的前面。所以,浮點數的表示範圍相對較大,但是精度相對較低。

二、定點數的詳解

在計算中,我們通常需要進行浮點數(實數)和定點數(整數)之間的轉換。有時候,我們需要把實數乘以一個精度因子,再將其轉換成整數,這就是定點數的表示方法。

#include <stdio.h>

#define Q        8        // 小數部分的位數
#define QQ        (1<<Q)    // 2^Q
#define QQ2       (1< %d\n", a, a_fix);
    printf("b: %.2lf -> %d\n", b, b_fix);
    printf("a+b: %.4lf\n", fix(a_fix + b_fix));
    return 0;
}

上述代碼實現了將小數部分為8位的實數轉化為整數操作,例如將2.25轉換為$2.25 \times 2^8=576$。

三、浮點數的詳解

在計算機內部,單精度浮點數32位,雙精度浮點數64位。由於存儲空間的限制,無法完全精確地表示實數。所以,計算機內部的浮點數通常採用科學計數法表示,在IEEE754標準中,單精度浮點數最高位表示符號,接著是指數部分,然後是尾數部分。

#include <stdio.h>

int main()
{
    float a = 1.2345;
    double b = 12.345;
    printf("a: %.10f\n", a);
    printf("b: %.15lf\n", b);
    return 0;
}

輸出結果為:

a: 1.2344999313
b: 12.345000000000000

從輸出結果可以看出,浮點數的精度不如定點數高。

四、小數點的移位問題

在浮點數的運算中,容易出現小數點的移位問題。比如,我們需要將一個浮點數加上一個整數,但是因為小數點位置的不同,可能會出現問題。

#include <stdio.h>

int main()
{
    double a = 1.0, b = 100000000000.0;
    int c = 1;
    printf("a+b: %.1lf\n", a+b);          // 輸出:100000000001.0
    printf("(a+c)+b: %.1lf\n", (a+c)+b);    // 輸出:100000000002.0
    printf("a+(c+b): %.1lf\n", a+(c+b));    // 輸出:100000000001.0
    return 0;
}

從輸出結果可以看出,在浮點數的運算中,加法並不滿足結合律。

五、避免浮點數誤差

為了避免浮點數運算中出現誤差,我們可以採用避免小數點移位的方法,即將小數轉換為整數進行運算。

#include <stdio.h>

int main()
{
    double a = 1.0, b = 100000000000.0;
    int a_fix = a * 1000;
    int b_fix = b;
    printf("a_fix+b_fix: %.1lf\n", (double)(a_fix+b_fix)/1000);    // 輸出:100000000001.0
    return 0;
}

上述代碼中,我們將浮點數乘以一個精度因子1000,再將其轉換為整數進行計算。最後再將計算結果轉換為浮點數。

六、整數溢出問題

在使用定點數時,有可能會出現整數溢出的問題。當定點數的位數不夠用時,需要向左移動小數點,此時整數位數就會增加,如果整數位數過大,就會超出計算機所能表示的範圍。

#include <stdio.h>

#define Q        3        // 小數部分的位數
#define QQ        (1<<Q)    // 2^Q
#define fract(x)  ((int)((x)*QQ+0.5))
#define fix(x)    ((double)(x)/QQ)

int main()
{
    double a = 128.0;
    int a_fix = fract(a);
    printf("a_fix: %d\n", a_fix);
    printf("2*a_fix: %d\n", 2*a_fix);  // 輸出:512,已經溢出
    return 0;
}

因此,在使用定點數時,要注意定點數的整數和小數部分的位數,以免溢出。

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/249627.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-12 17:11
下一篇 2024-12-12 17:11

相關推薦

  • int類型變數的細節與注意事項

    本文將從 int 類型變數的定義、聲明、初始化、範圍、運算和類型轉換等方面,對 int 類型變數進行詳細闡述和講解,幫助讀者更好地掌握和應用 int 變數。 一、定義與聲明 int…

    編程 2025-04-29
  • Python中將字元串轉化為浮點數

    本文將介紹在Python中將字元串轉化為浮點數的常用方法。在介紹方法之前,我們先來思考一下這個問題應該如何解決。 一、eval函數 在Python中,最簡單、最常用的將字元串轉化為…

    編程 2025-04-29
  • 浮點數:float小數點後幾位C

    在編程中,浮點數是一種常見的數據類型之一,而float小數點後幾位C則是指浮點數在計算機中存儲的精度問題。在編寫程序的時候,我們需要考慮浮點數的精度問題,以避免演算法出錯或結果不準確…

    編程 2025-04-28
  • Python入門:輸入三個浮點數並進行計算

    本文將介紹如何使用Python輸入三個浮點數,並且進行計算,最後輸出結果。 一、輸入三個浮點數 在Python中,我們可以使用input()函數來獲取用戶的輸入。為了輸入三個浮點數…

    編程 2025-04-28
  • 浮點型數據的細節揭秘

    一、基本概念 浮點型數據是指可以表示實數的一種數據類型。在C語言中,浮點型數據有兩種類型:float(單精度浮點數)和double(雙精度浮點數)。其中,float數據類型佔用4個…

    編程 2025-04-25
  • Latex加粗的使用細節

    一、Latex加粗的基本使用方法 在Latex中,加粗的基本語法是使用 \textbf{要加粗的文字} 。比如下面這個例子: The \textbf{quick} brown \t…

    編程 2025-04-25
  • :Darkgray的細節探索

    一、顏色值解析 對於前端開發來說,顏色選擇是一項非常常見的任務。要實現一個​​優雅的前端設計,我們需要學會如何選擇恰當的顏色。在這裡,我將介紹darkgray,這是一種常用的顏色,…

    編程 2025-04-24
  • biba模型的細節探究

    一、無 biba模型是一種多級安全模型,它強調了完整性比機密性更為重要。在biba模型中,所有對象和主體都被賦予一個完整性級別,而更高完整性級別的主體只能讀取更低完整性級別的對象。…

    編程 2025-04-22
  • QString contains:細節決定成敗

    一、基本概念 QString是Qt中最為常用的字元串類,其中很重要的一個函數是contains。contains函數的作用是用於判斷字元串是否包含指定的字元串,例如: QStrin…

    編程 2025-04-20
  • 切面表達式:細節決定成敗

    一、切面表達式註解 註解是Java中非常重要的一種語法標記,Spring AOP中也通過註解的方式來定義切面。在定義切面時,可以使用@Aspect註解表示一個切面類,也可以使用@B…

    編程 2025-04-13

發表回復

登錄後才能評論