Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#从浮点变量中获取数字_C#_.net_Floating Point - Fatal编程技术网

C#从浮点变量中获取数字

C#从浮点变量中获取数字,c#,.net,floating-point,C#,.net,Floating Point,我有一个浮点变量,只想得到逗号后面的部分,所以如果我有3.14。我想得到14作为一个整数。我该怎么做呢?您可以从值本身减去整数部分来检索小数部分 float x = 3.14 float fractionalPortion = x - Math.Truncate(x); 然后,您可以将其相乘,以任意精度获得表示为整数的分数部分 将小数部分映射到整数有一些挑战-许多浮点数不能表示为以10为基数的整数,因此可能需要比整数更多的数字来表示 另外,像3.1和3.01这样的数字的情况又如何呢?直接映射到

我有一个浮点变量,只想得到逗号后面的部分,所以如果我有3.14。我想得到14作为一个整数。我该怎么做呢?

您可以从值本身减去整数部分来检索小数部分

float x = 3.14
float fractionalPortion = x - Math.Truncate(x);
然后,您可以将其相乘,以任意精度获得表示为整数的分数部分

将小数部分映射到整数有一些挑战-许多浮点数不能表示为以10为基数的整数,因此可能需要比整数更多的数字来表示


另外,像3.1和3.01这样的数字的情况又如何呢?直接映射到整数都会导致1。

欺骗的方法是:

float x = 3.14
int fractionalPortionAsInt = (int) (100 * (x - Math.Floor(x)));
    private Int32 FractionalPart(double n)
    {
        string s = n.ToString("#.#########", System.Globalization.CultureInfo.InvariantCulture);
        return Int32.Parse(s.Substring(s.IndexOf(".") + 1));
    }

编辑2:好的。这是我能想到的最偏执的永不失败的版本。这将返回浮点数小数部分的前9位(如果没有那么多的话,则不超过9位)。这保证不会使Int32溢出。我们使用不变区域性,因此我们知道可以使用句点作为小数分隔符。

为了提出不同于其他分隔符的建议,我们使用了一种扩展方法(使用类似于David的方法):

编辑: 我没有使用“最佳”答案,因为它省略了最难的部分,即转换任意十进制数,并且不适用于负数。我在David的回答中添加了要求的更正。

以下是“非加热”回答:

double n=3.14;
常数双精度=0.000001;
//我们不能很好地处理负数
if(n<0)
n=0-n;
//删除n的整数部分
n-=数学楼层(n);
int结果=0;
而(n>精度)
{
//将n的1/10位移到1的位置
n*=10;
//得到那个数字吗
整数位数=(整数)数学楼层(n);
//将结果向左移位并添加数字
结果=结果*10+位;
//从n中删除1的数字
n-=数字;
}
//答案是结果;

我们使用精度而不是0来弥补浮点数不能很好地处理十进制数这一事实。您可以调整它以适应您的应用。这就是为什么我认为“欺骗”字符串的方式实际上更好。

< P>实际上,直到现在所有的解决方案都是错误的,因为他们不认为使用<代码>数学。
这是另一个版本,它还告诉我小数部分的组成部分有多少位数,这是我需要的

public static int GetFractionalPartAsInt(decimal n, out int numOfFractionalDigits)
{
  n -= Math.Truncate(n);
  n = Math.Abs(n);

  int numOfFractionalDigitsValue = 0;
  // When n != Math.Truncate(n), we have seen all fractional decimals.
  while (n != Math.Truncate(n))
  {
    n *= 10;
    numOfFractionalDigitsValue++;
  }

  numOfFractionalDigits = numOfFractionalDigitsValue;

  return (int)n;
}
这个想法和大卫的答案(他的非作弊版本)很相似。但是,我使用了十进制类型而不是double,这会减慢速度,但会提高准确性。如果我将David(同样是非作弊版本)的答案转换为十进制类型(在这种情况下,他的“精度”变量可以更改为常量零),那么我的答案运行速度大约快25%。请注意,我还更改了他的代码,以便在测试中提供小数位数。

试试看

float n = 3.14f;
int fractionalPart = new System.Version(n.ToString()).Minor;

大卫的“作弊版”答案目前似乎并不流行,但在一天中的大部分时间里,我都在研究这个问题后,找到了System.version类。它有一个接受字符串的构造函数。使用Reflector,我看到它通过将字符串拆分成一个数组来工作。我运行了一个测试,得到了任意数字1234567891.1234567891m的小数部分。在1000000次迭代中,它比我发布的另一个答案快50%,尽管为了版本构造函数,我首先必须将十进制数转换为字符串。因此,当使用字符串转换概念似乎是一条光明的道路时,David遇到了一个坏的突破。微软做到了。

这将导致一些奇怪的不可预测的值

浮点数不存储为十进制-指数部分是2的幂,而不是10

这意味着某些数字(例如1.1)不能准确地表示为浮点(1.1的结果类似于1.099999998)

问题是,对于某些数字,起始数字可能不是其中之一,而小数部分本身可能是

你的号码是x.y

得到整数x部分

你做x.y-x得到0.y

有时x.y可以表示为浮点,而0.y不能,因此,与其得到y,不如得到一些包含大量0或9的大值

@大卫的“欺骗”方式实际上是最好的方式——无论如何,最不容易出现这个问题


然而,我想看看为什么你需要这样做——浮点数对于非常快速的数学来说是很棒的,但是对于准确性来说有点垃圾。如果精度很重要,请使用
decimal
类型-该类型可以保证存储精确的值,但代价是计算速度较慢。

我发现了一种快速的方法,可以使用位掩码和GetBits方法将浮点/双精度转换为代表其数字的整数。。。只有当结果符合32位整数时,它才有效,但它仍然非常光滑。。。我不能相信这一点,但请看一看:


以防万一,有些人想用另一种作弊方式:

float x = 5.2f;
int decimalPart = Math.Round((x - Math.Truncate(x))*100)

其中100用于移位小数部分。

使用正则表达式(REGEX)

使用乘法器[即10乘以N的幂(例如10²或10³),其中N是小数位数]

   // multiplier is " 10 to the power of 'N'" where 'N' is the number 
   // of decimal places
   int multiplier = 1000;  
   double double_value = 12.345;
   int double_result = (int)((double_value - (int)double_value) * multiplier);

//输出345

这不会将分数部分作为整数。这给了他一个0.14的浮动;)不会这样做,因为karstenkousgaard想要14作为答案,而不是0,14更新的答案来包含所需的乘法。你不能乘以大于位数的10的幂。。。这就省去了问题的难点。数学呢?截断而不是地板?对于3.14,它返回10*(3.14-0.14)=30doh。10*(3.14-3)=1.4=(int)1就是我的意思。@jitter:这意味着它只对2位有效,而不是任何普通的浮点。您必须指定一个位数。3.14我
float n = 3.14f;
int fractionalPart = new System.Version(n.ToString()).Minor;
float x = 5.2f;
int decimalPart = Math.Round((x - Math.Truncate(x))*100)
string input_decimal_number = "3.14";
var regex = new System.Text.RegularExpressions.Regex("(?<=[\\.])[0-9]+");
if (regex.IsMatch(input_decimal_number))
{
    string decimal_places = regex.Match(input_decimal_number).Value;
}
 var float_number = 12.345;
 var result = float_number - Math.Truncate(float_number);
   // multiplier is " 10 to the power of 'N'" where 'N' is the number 
   // of decimal places
   int multiplier = 1000;  
   double double_value = 12.345;
   int double_result = (int)((double_value - (int)double_value) * multiplier);