如何在C ++中计算float中的小数位数?

时间:2014-01-12 19:20:44

标签: c++ floating-point

我需要检查我的任务的浮点数中的小数位数,以验证输入,我该怎么做?

5 个答案:

答案 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
}