サンプルコード:
int main() {
float f = 123.542;
int i = (int)f;
printf("%d\n",i);
}
123.3443は、浮動小数点数で正確に表すことはできません。32ビットの浮動小数点数では、実際には16166984 / 131072
として表されます。これは、実際には123.3443ではなく123.34429931640625です。 (約6.8 x 10 ^ -7だけずれています。)
これが本当に望ましい結果である場合(おそらくそうではないでしょう)、IEEE-754 floatがどのように機能するかを確認し、お気に入りの任意精度の数学スイートを引き出します。 「舞台裏」で何が起こっているのかを理解したら、正確な表現を生成することはtoo難しいことではありません。 「十分に近い」丸められた表現を生成することは、実際にははるかに困難です。 :)
int i = (int) (f * 10000 + 0.5);
float
の数値と同等の整数f
_float f=123.456;
_
modff()
を使用して作成できます
_float integral, fractional;
char str[50], temp[20];
fractional = modff(f, &integral);
_
現在、integral
には整数部(123.000000など)があり、fractional
には小数部(0.456000など)があります。
浮動小数点数(この場合はf
)が負の場合、integral
とfractional
の両方が負になります。
できるよ
_if(fractional<0)
{
fractional = -fractional;
}
_
それを改善するために。
さて、
_sprintf(temp, "%g", fractional);
_
_%g
_形式指定子は末尾のゼロを削除し、temp
は_"0.456"
_を持つようになります。
_sprintf(str, "%g%s", integral, temp[1]=='.'?temp+2:"");
_
_temp[1]=='.'?
_は、小数部が_0
_の場合、_0
_ではなく_0.000000
_であったため、fractional
を出力するときに小数点がなかったためです。 temp
の2番目の文字が_.
_でない場合、fractional
はゼロであり、気にする必要はありません。
今回の場合、str
は_"123456"
_になります。しかし、それは文字列の形式です。それを整数に変換する必要があります。そのためにはstrtol()
を使用します。
_long l=strtol(str, NULL, 10);
if(l>INT_MAX || errno==ERANGE)
{
printf("\noverflow");
}
else
{
printf("\n%d", strtol(str, NULL, 10));
}
_
strtol()
の戻り値とerrno
の戻り値(_errno.h
_から)を確認できます。オーバーフローが発生したかどうかを確認するには、ERANGE
かどうかを確認します。
結果の値をint
に格納できるかどうかを確認するには、最初にstrtol()
から返された値を_long int
_に格納し、それが_INT_MAX
_より大きいかどうかを確認します(_limits.h
_)。
結果の精度は、浮動小数点数が2進数で表される精度に依存することに注意してください。
float
に10^x
を乗算します。ここで、x
は、小数の後の桁数で、int
にキャストします。
変換された数値を繰り返し処理する必要がなく、数値を整数に変換することのみを目的としている場合、最も簡単な方法は、sprintfを使用し、10のべき乗のルールを使用してforループで小数を合計することです。数学に「正確な精度」が必要な場合は、BCDを使用します。次のアルゴリズムを使用すると、「正確な精度」の桁数を切り捨てることができます。
#include "math.h"
long ConvertToScaledInteger (float value, int significantDigits = -1)
{
// Note: for 32-bit float, use long return and for double use long long.
if (significantDigits < 1) // Ditch the '-' and the '.'
significantDigits += 2;
else
++significantDigits; // Ditch the '.'
char* floatingPointString = malloc(sizeof (char) * (4 + FLT_MANT_Dig - FLT_MIN_EXP));
/*< This solution is for a 32-bit floating point number. Replace FLT
with DBL, and it will produce the max number of chars in a 64-bit
float string. */
if (significantDigits < 0) //< Then use all of the float's digits.
{
sprintf (floatingPointString , "%f", floatingPointNumber);
}
else //< Then truncate the number of decimal places.
{
char decimalPlaceString[9];
char percentString = "%\0";
sprintf (decimalPlaceString, "%s%if", percentString , significantDigits);
sprintf (floatingPointString , decimalPlaceString, value);
}
int stringLength = strlen (floatingPointString),
index;
long returnValue = 0;
double powerOfTen = 10.0,
currentValue;
// Find if we have an ending of .0, and backtrack.
if (floatingPointString[stringLength - 1] == '0' && floatingPointString[stringLength - 2] == '.')
index = stringLength - 3;
else
index = stringLength - 1;
for (; index > 0; --index)
{
if (floatingPointString[index] == '.')
--index;
// Subtract ASCII '0' converts ASCII to integer.
currentValue = (double) floatingPointString[index] - '0';
returnValue += (long) currentValue * pow (10.0, powerOfTen);
powerOfTen += 1.0;
}
if (floatingPointString[0] == '-')
returnValue *= -1;
return returnValue;
}