我有以下 C 代碼來確定雙精度值的小數位。它使用sprintf()'s%f來結束一個沒有浮點不精確的字串。是否存在sprintf()無法正確消除浮點不精確性的風險,或者該功能是否可以安全使用?
#include <stdio.h>
#include <stdbool.h>
#define MAX_STRING 256
int getDecimalPlaces(double n)
{
char string[MAX_STRING];
int numberOfDecimalPlaces = 0;
int i = sprintf(string, "%f", n);
bool countZero = false;
for (int j = i - 1; j > 0; j--)
{
if (string[j] == '.')
break;
if (!countZero && string[j] != 48)
countZero = true;
if (countZero)
numberOfDecimalPlaces ;
}
return numberOfDecimalPlaces;
}
我呼叫數字函式來對它們執行數學運算(最小公乘)。我需要整數來進行此操作,以便搜索小數位數最多的數字。然后我將每個數字乘以 10 ^(大多數小數位)。處理的數字是用戶輸入的,屬于線性方程組。在大多數情況下,兩位小數就足夠了。
數字本身不必非常精確,但它們的小??數位必須與用戶輸入的內容相匹配。
uj5u.com熱心網友回復:
您的函式只能為任何有限數生成 6 位小數,因此它不能回傳大于的小數位數,6并且回傳的小數位數可能比預期的小得多:如果該值不是整數但足夠接近,則該函式將回傳0,例如:getDecimalPlaces(1.0000004)或getDecimalPlaces(1.9999996)。
%f使用固定的小數位數格式化數字,您可以使用精度欄位(例如%.10f. 它默認為6.
如果要確定n明確表示該值所需的小數位數,則應使用20.18g和處理可能為-1和之間的值生成的指數部分1。
但是請注意,該double型別在內部對浮點值使用二進制表示。除非該值是 2 的負冪的精確倍數,否則表示形式是其十進制表示形式的近似值。
例如1.5,精確表示,沒有近似值,但0.1不是,就像 1/3 不能用十進制表示精確表示。
的內部表示0.1是近似的,但根據 的實作sprintf(),將此近似值轉換為十進制可以產生0.1000000000000000000013552527156068805425093160010874271392822265625或只是0.1,因為兩者都將轉換回相同的值。
sprintf在您的函式中使用編碼是不安全的:對于一個非常大的數字,大于 1e250,snprintf將產生超過 256 個字符并寫入超出陣列末尾。使用起來更安全snprinf。
如果您的目標是將值轉換為最多 6 位小數且沒有指數的十進制形式,您可以更改您可以使用此修改后的版本:
#include <stdio.h>
int convertValue(char *dest, size_t size, double d, int maxplaces) {
int len = snprintf(dest, "%.*f", maxplaces, d);
while (n > 0 && string[len - 1] == '0')
string[--len] = '\0';
if (len > 0 && string[len - 1] == '.')
string[--len] = '\0';
return len;
}
編輯:出于您的目的,您希望將數字轉換為整數。確保您使用round(d * power_of_10)以確保正確轉換。如果沒有round(),您可能會得到不正確的轉換,例如0.7 * 10轉換為6而不是7.
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/407562.html
標籤:
上一篇:C中的陣列操作函式
下一篇:C中的結構-需要一些建議
