サンプルコード:浮動小数点値を123.3443〜1233443のような正確な精度の整数に変換する方法はありますか?
int main() {
float f = 123.542;
int i = (int)f;
printf("%d\n",i);
}
サンプルコード:浮動小数点値を123.3443〜1233443のような正確な精度の整数に変換する方法はありますか?
int main() {
float f = 123.542;
int i = (int)f;
printf("%d\n",i);
}
int i = (int) (f * 10000 + 0.5);
本当に役に立たない答え(質問者は彼が求めたものを正確に得ることができます)。おそらく彼が心に持っていたものではないでしょう。 – AoeAoe
乗算float
x
は、小数点の後にあなたがしたいと、その後int
にキャストどのように多くの桁である10^x
によります。
これは動作しますが、あらかじめ必要な小数点以下の桁数を知っていることを前提としています。 – PeterAllenWebb
123.3443は、32ビット浮動小数点数では正確には16166984/131072
と表されます。実際には123.34429931640625で、123.3443ではありません。
これが本当に望む結果なら(おそらくそうではないかもしれませんが)、IEEE-754浮動小数点演算がどのように機能するかを見て、好きな任意の値を取り出して、高精度の数学スイートです。 「舞台裏で」何が起こっているのかを理解したら、正確な表現を生成することはでもではありません。 「十分に近い」表現を生成することは実際はずっと困難です。あなたが変換された数の任意の繰り返し処理を行う必要はありませんし、唯一の整数に数値を変換するために探している場合:)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int f2i(float v, int size, int fsize){
char *buff, *p;
int ret;
buff = malloc(sizeof(char)*(size + 2));
sprintf(buff, "%*.*f", size, fsize, v);
p = strchr(buff, '.');
while(*p=*(p+1))p++;
ret = atoi(buff);
free(buff);
return ret;
}
int main(){
float f = 123.3443;
printf("%d\n", f2i(f, 7, 4));
f=123.542;
printf("%d\n", f2i(f, 6, 3));
return 0;
}
は、最も簡単な方法は、その後、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;
}
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"
を持つことになります。
temp[1]=='.'?
が行われ
sprintf(str, "%g%s", integral, temp[1]=='.'?temp+2:"");
小数部分が0
であれば、それは0
なく0.000000
してきたと同じようにfractional
を印刷中にあるため、何の小数点がなかっwould'v。 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));
}
あなたは(errno.h
から。それがERANGE
であるかどうかを確認してください)戻りstrtol()
の値とerrno
のことをチェックすることがオーバーフローが発生したかどうかを確認します。得られた値は、int
に格納することができる場合(これはlimits.h
に'S)最初long int
にstrtol()
によって返される値を格納し、それは、INT_MAX
よりも大きいかどうか、確認するに
。
結果の精度は、浮動小数点数が2進数で表される精度に依存することに注意してください。
数字が「1.999999999999」の場合はどうなりますか?ヒント:あなたがしようとしていることは不可能です。 (あるいは、少なくともバイナリ浮動小数点ではあまり定義されていません) – Mysticial
おそらく、ゼロに近い(許容度を持つ)部分の左にある浮動小数点数を得ることでしょうか? – markw
@Mysticial:FP指数が2の累乗であるため、実際には浮動小数点で常に可能です。通常、結果はあなたの望むものではありません(たとえば、正確なバイナリ分数の場合のみ)。 – duskwuff