strtod函數詳解

strtod是C語言中的標準函數,主要用來把字元串轉換成double類型的浮點數。它的原型如下:

double strtod(const char *nptr, char **endptr);

其中nptr為待轉換的字元串指針,endptr指向待轉換的字元串中第一個非數字或點的字元的指針。如果沒有執行任何轉換,endptr指向待轉換字元串的起始地址。

一、字元串轉換

strtod函數的主要用途是將字元串轉換成double類型的浮點數,這是它最常用的功能。在轉換時,strtod會自動跳過前導空格,並處理負數、科學計數法等特殊情況。

以下是一個簡單的例子:

const char *str = "3.1415926";
char *end;
double num = strtod(str, &end);

在這個例子中,strtod函數執行後num的值為3.1415926,end指針指向字元串結尾的’\0’。需要注意的是,如果待轉換的字元串中包含非數字或點之外的字元,strtod函數只會轉換到第一個非數字或點之前的部分,後面的內容會被忽略掉。

下面是一個包含特殊情況的例子:

const char *str = "-1.23E-4";
char *end;
double num = strtod(str, &end);

在這個例子中,待轉換的字元串包含負號、小數點和科學計數法三個特殊情況。在轉換時,strtod會將它們轉換成對應的浮點數。執行後num的值為-0.000123,end指針指向字元串結尾的’\0’。

二、錯誤處理

在實際應用中,待轉換的字元串可能會包含一些不能正確轉換成浮點數的字元,或者指針參數傳入不正確等情況。為了在這些情況下保證程序的穩定性,strtod函數提供了一些錯誤處理機制。

1.轉換失敗

如果待轉換的字元串中不包含任何數字或點,或者出現了既非數字又不是點的字元,strtod函數會返回0.0並賦值全局變數errno為ERANGE。例如:

const char *str = "abc";
char *end;
double num = strtod(str, &end);
if (*end == '\0' && errno == ERANGE) {
    printf("轉換失敗\n");
}

在這個例子中,因為字元串中既沒有數字也沒有點,所以轉換失敗,num的值為0.0,end指針指向字元串結尾的’\0’,errno被賦值為ERANGE。

2.指針參數不正確

如果指針參數end傳入了不正確的值,strtod函數也會返回0.0並賦值全局變數errno為EINVAL。例如:

const char *str = "3.14";
double num = strtod(str, NULL);
if (errno == EINVAL) {
    printf("指針參數不正確\n");
}

在這個例子中,因為指針參數end傳入了NULL,所以調用函數時會返回0.0,並將errno賦值為EINVAL。

3.溢出

如果待轉換的字元串表示的浮點數超出了double類型的範圍,strtod函數會返回正負無窮大,並賦值全局變數errno為ERANGE。例如:

const char *str = "1e308";
char *end;
double num = strtod(str, &end);
if (*end == '\0' && errno == ERANGE) {
    printf("超出範圍\n");
}

在這個例子中,因為待轉換的字元串表示的浮點數超過了double類型所能表示的最大值,所以函數調用會返回正無窮大,end指針指向字元串結尾的’\0’,errno被賦值為ERANGE。

三、函數實現

strtod函數的實現可分為以下幾步:

1.跳過前導空格和符號判斷

strtod函數會先跳過待轉換字元串中的空格和製表符等空白字元,然後判斷第一個非空白字元是不是符號(+或-)。如果是,會將該符號的正負性作為標記(sign)存儲下來,然後將指針向後移動一位。

2.處理小數部分

接下來,strtod函數會處理小數部分(如果有的話)。它會遍歷字元串,直到遇到非數字或點的字元。在遍歷的過程中,strtod會將遇到的數字按權相加的方式計算出浮點數的整數部分(integer part)和小數部分(fraction part)。例如,在處理字元串”3.14″時,strtod會先計算出整數部分3,然後根據小數點後面的數字1和4計算出小數部分0.14(1/10 + 4/100)。

3.處理指數部分

如果待轉換字元串中包含科學計數法(例如3.14E5),strtod函數會處理指數部分。它會提取出E或e後面的數字作為指數(exponent),然後將整個浮點數乘以10的exponent次方。例如,在處理字元串”3.14E5″時,strtod會先計算出浮點數3.14,然後將其乘以10的5次方。

4.返回結果

最後,strtod函數會根據前面計算出來的數值、符號和指數等信息,計算出最終的浮點數,並把它返回。

下面是一個簡化版的strtod函數實現:

double my_strtod(const char *nptr, char **endptr) {
    // 跳過前導空格和符號
    char *p = (char *)nptr;
    while (isspace(*p)) p++;
    int sign = 1;
    if (*p == '+') {
        p++;
    } else if (*p == '-') {
        p++;
        sign = -1;
    }

    // 處理小數部分
    double integer_part = 0.0;
    double fraction_part = 0.0;
    double divisor = 1.0;
    while (isdigit(*p) || *p == '.') {
        if (*p == '.') {
            divisor = 10.0;
            p++;
            continue;
        }
        if (divisor == 1.0) {
            integer_part = integer_part * 10.0 + (*p - '0');
        } else {
            fraction_part += (*p - '0') / divisor;
            divisor *= 10.0;
        }
        p++;
    }

    // 處理指數部分
    int exponent = 0;
    if (toupper(*p) == 'E') {
        p++;
        int exp_sign = 1;
        if (*p == '+') {
            p++;
        } else if (*p == '-') {
            p++;
            exp_sign = -1;
        }
        while (isdigit(*p)) {
            exponent = exponent * 10 + (*p - '0');
            p++;
        }
        exponent *= exp_sign;
    }

    // 返回結果
    if (endptr != NULL) {
        *endptr = p;
    }
    return sign * (integer_part + fraction_part) * pow(10, exponent);
}

四、總結

strtod函數是C語言中常用的一個函數,主要用來將字元串轉換成double類型的浮點數。在實際應用中,strtod函數還會根據待轉換字元串的不同情況返回不同的錯誤碼,方便程序員進行錯誤處理。

本文主要闡述了strtod函數的用法和實現方法,並給出了一個簡化版的實現代碼,供讀者參考。

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

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
FMFB的頭像FMFB
上一篇 2024-11-05 16:51
下一篇 2024-11-05 16:51

相關推薦

  • Python中引入上一級目錄中函數

    Python中經常需要調用其他文件夾中的模塊或函數,其中一個常見的操作是引入上一級目錄中的函數。在此,我們將從多個角度詳細解釋如何在Python中引入上一級目錄的函數。 一、加入環…

    編程 2025-04-29
  • Python中capitalize函數的使用

    在Python的字元串操作中,capitalize函數常常被用到,這個函數可以使字元串中的第一個單詞首字母大寫,其餘字母小寫。在本文中,我們將從以下幾個方面對capitalize函…

    編程 2025-04-29
  • Python中set函數的作用

    Python中set函數是一個有用的數據類型,可以被用於許多編程場景中。在這篇文章中,我們將學習Python中set函數的多個方面,從而深入了解這個函數在Python中的用途。 一…

    編程 2025-04-29
  • 三角函數用英語怎麼說

    三角函數,即三角比函數,是指在一個銳角三角形中某一角的對邊、鄰邊之比。在數學中,三角函數包括正弦、餘弦、正切等,它們在數學、物理、工程和計算機等領域都得到了廣泛的應用。 一、正弦函…

    編程 2025-04-29
  • 單片機列印函數

    單片機列印是指通過串口或並口將一些數據列印到終端設備上。在單片機應用中,列印非常重要。正確的列印數據可以讓我們知道單片機運行的狀態,方便我們進行調試;錯誤的列印數據可以幫助我們快速…

    編程 2025-04-29
  • Python3定義函數參數類型

    Python是一門動態類型語言,不需要在定義變數時顯示的指定變數類型,但是Python3中提供了函數參數類型的聲明功能,在函數定義時明確定義參數類型。在函數的形參後面加上冒號(:)…

    編程 2025-04-29
  • Python定義函數判斷奇偶數

    本文將從多個方面詳細闡述Python定義函數判斷奇偶數的方法,並提供完整的代碼示例。 一、初步了解Python函數 在介紹Python如何定義函數判斷奇偶數之前,我們先來了解一下P…

    編程 2025-04-29
  • Python實現計算階乘的函數

    本文將介紹如何使用Python定義函數fact(n),計算n的階乘。 一、什麼是階乘 階乘指從1乘到指定數之間所有整數的乘積。如:5! = 5 * 4 * 3 * 2 * 1 = …

    編程 2025-04-29
  • Python函數名稱相同參數不同:多態

    Python是一門面向對象的編程語言,它強烈支持多態性 一、什麼是多態多態是面向對象三大特性中的一種,它指的是:相同的函數名稱可以有不同的實現方式。也就是說,不同的對象調用同名方法…

    編程 2025-04-29
  • 分段函數Python

    本文將從以下幾個方面詳細闡述Python中的分段函數,包括函數基本定義、調用示例、圖像繪製、函數優化和應用實例。 一、函數基本定義 分段函數又稱為條件函數,指一條直線段或曲線段,由…

    編程 2025-04-29

發表回復

登錄後才能評論