我需要检查我的任务的浮点数中的小数位数,以验证输入,我该怎么做?
答案 0 :(得分:4)
你不能希望这样做,因为float以二进制浮点而不是十进制保存。因此,例如,0.1不能在二进制浮点变量中精确表示。如果你不能准确地表示数字,那么你无法推断它的表示。
如果您希望将数字表示为十进制,则必须使用十进制表示而不是二进制表示。
有关此主题的必读内容:What Every Computer Scientist Should Know About Floating-Point Arithmetic
答案 1 :(得分:4)
输入时应验证输入。您应该检查输入文本并确定它是否可接受。
当十进制数字转换为二进制浮点数时,该值通常是四舍五入的,因为二进制浮点数不能精确地表示大多数十进制值。因此,当您检查作为此转换结果的float
时,您将不再拥有原始输入,因此您无法对原始输入执行精确操作。
答案 2 :(得分:1)
这是我曾经发现的一个实现,比如user2699298的答案,但是应该修复一些怪癖。我没有测试所有可能的组合,但它似乎对下面显示的测试做得很好。我建议你自己决定是否足够......
#include <cmath>
template< class T >
unsigned NumberOfDecimalPlaces( const T& num, const unsigned maxNumberOfDecimalPlacesReturned, const T& threshold = 1e-12 )
{
static_assert( std::is_floating_point< T >::value,
"NumberOfDecimalPlaces if for floating point numbers only" );
T number = std::abs( num );
unsigned numDecimalPlaces = 0;
while( ( number - std::floor( number ) ) > threshold &&
( std::ceil( number ) - number ) > threshold )
{
if( ++numDecimalPlaces >= maxNumberOfDecimalPlacesReturned )
break;
number *= 10.0;
}
return numDecimalPlaces;
}
一些测试:
TEST( NumberOfDecimalPlaces_Is_0_For_0 )
{
CHECK_EQUAL( 0u, NumberOfDecimalPlaces( 0.0, 20 ) );
}
TEST( NumberOfDecimalPlaces_Yields_Max )
{
CHECK_EQUAL( 5u, NumberOfDecimalPlaces( 0.11121212, 5 ) );
CHECK_EQUAL( 5u, NumberOfDecimalPlaces( 0.00000001, 5 ) );
}
TEST( NumberOfDecimalPlaces_WorksOk_ForPrettyNormalNumbers )
{
CHECK_EQUAL( 1u, NumberOfDecimalPlaces( 0.1, 20 ) );
CHECK_EQUAL( 1u, NumberOfDecimalPlaces( 0.8, 20 ) );
CHECK_EQUAL( 8u, NumberOfDecimalPlaces( 0.11121212, 20 ) );
CHECK_EQUAL( 8u, NumberOfDecimalPlaces( 0.00000001, 20 ) );
CHECK_EQUAL( 7u, NumberOfDecimalPlaces( 0.0000001, 20 ) );
//this is represented as 0.0000000109999999
CHECK_EQUAL( 9u, NumberOfDecimalPlaces( 0.000000011, 20 ) );
}
答案 3 :(得分:1)
问题通常是“我需要多少位数(精确度)?”。
让我们取两个分数,1/10和22/7。
使用1/10(评估为0.1),小数点后面只有一位数或0.1000仍然有效。在网上搜索“重要数字”。
分数为22/7,小数点后有多少位数?
对于无理数,可能存在重复或不重复的序列。例如,1/3,在第一个小数后重复。然而,PI的值不重复?
或者您要求小数点前的位数?
可以使用log
函数来回答这个问题。
number of digits before decimal point = log(number) / log(10);
答案 4 :(得分:0)
int decimals_float (float number){
float num = number; // local variable to hold the number
int count = 0; // variable to count the decimals
num = abs(num); // take the absolute value of the number (no negatives)
num = num - (int)num; // take off the digit and leave only decimals in the number
while(num >= 0.1){ // checking until >= 0.1, because if we use != or >= 0 it might not work
num *= 10; // multiply the number by 10, to remove one decimal
count++; // add one to the decimals
num -= (int)num; // take off the digit and leave only decimals in the number
}
return count; // return amount of decimals
}