Single Структура
Определение
Важно!
Некоторые сведения относятся к предварительной версии продукта, в которую до выпуска могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
Представляет число одиночной точности с плавающей запятой.
public value class float : IComparable, IComparable<float>, IConvertible, IEquatable<float>, IFormattable
public value class float : IComparable, IComparable<float>, IConvertible, IEquatable<float>, ISpanFormattable
public value class float : IComparable, IConvertible, IFormattable
public value class float : IComparable, IComparable<float>, IEquatable<float>, IFormattable
public struct Single : IComparable, IComparable<float>, IConvertible, IEquatable<float>, IFormattable
public struct Single : IComparable, IComparable<float>, IConvertible, IEquatable<float>, ISpanFormattable
[System.Serializable]
public struct Single : IComparable, IConvertible, IFormattable
[System.Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
public struct Single : IComparable, IComparable<float>, IConvertible, IEquatable<float>, IFormattable
public struct Single : IComparable, IComparable<float>, IEquatable<float>, IFormattable
type single = struct
interface IConvertible
interface IFormattable
type single = struct
interface IConvertible
interface ISpanFormattable
interface IFormattable
[<System.Serializable>]
type single = struct
interface IFormattable
interface IConvertible
[<System.Serializable>]
[<System.Runtime.InteropServices.ComVisible(true)>]
type single = struct
interface IFormattable
interface IConvertible
type single = struct
interface IFormattable
Public Structure Single
Implements IComparable, IComparable(Of Single), IConvertible, IEquatable(Of Single), IFormattable
Public Structure Single
Implements IComparable, IComparable(Of Single), IConvertible, IEquatable(Of Single), ISpanFormattable
Public Structure Single
Implements IComparable, IConvertible, IFormattable
Public Structure Single
Implements IComparable, IComparable(Of Single), IEquatable(Of Single), IFormattable
- Наследование
- Атрибуты
- Реализации
Комментарии
SingleТип значения представляет собой 32-разрядное число с одинарной точностью и значениями от отрицательного 3.402823 E38 до положительного 3.402823 E38, а также положительного или отрицательного нуля,, PositiveInfinity NegativeInfinity , а не числа ( NaN ). Он предназначен для представления очень больших значений (например, расстояния между планеты или ГАЛАКСИЕС) или чрезвычайно малым (например, молекулярное масса вещества в килограммах) и часто являются неточными (например, расстояние от земли до другой солнечной системы). SingleТип соответствует стандарту IEC 60559:1989 (IEEE 754) для бинарной арифметики с плавающей запятой.
Эта статья состоит из следующих разделов:
System.Single предоставляет методы для сравнения экземпляров этого типа, преобразования значения экземпляра в строковое представление и преобразования строкового представления числа в экземпляр этого типа. Сведения о том, как коды спецификации формата управляют строковым представлением типов значений, см. в разделе Типы форматирования, строки стандартных числовых форматови строки настраиваемых числовых форматов.
Представление и точность с плавающей точкой
SingleТип данных хранит значения с плавающей запятой одиночной точности в 32-разрядном двоичном формате, как показано в следующей таблице.
Отделение | Bits |
---|---|
Значащим или мантисса | 0-22 |
Показатель степени | 23-30 |
Знак (0 = положительный, 1 = отрицательный) | 31 |
Точно так же, как десятичные дроби не могут точно представлять некоторые дробные значения (например, 1/3 или Math.PI ), двоичные дроби не могут представлять некоторые дробные значения. Например, 2/10, которая точно представляется в виде десятичной дроби 2, представляется в виде 0011111001001100 в виде двоичной дроби с шаблоном "1100", повторяющимся до бесконечности. В этом случае значение с плавающей запятой обеспечивает неточное представление числа, которое оно представляет. Выполнение дополнительных математических операций с исходным значением с плавающей запятой часто приводит к нехватке точности. Например, если сравнить результаты умножения 3 на 10 и добавить 3 в. 3 9 раз, вы увидите, что сложение выдает менее точный результат, так как включает восемь дополнительных операций, чем умножение. Обратите внимание, что такое нарушение четности очевидно только при отображении двух Single значений с помощью строки стандартного числового форматаR, которая при необходимости отображает все 9 знаков точности, поддерживаемые Single типом.
using System;
public class Example
{
public static void Main()
{
Single value = .2f;
Single result1 = value * 10f;
Single result2 = 0f;
for (int ctr = 1; ctr <= 10; ctr++)
result2 += value;
Console.WriteLine(".2 * 10: {0:R}", result1);
Console.WriteLine(".2 Added 10 times: {0:R}", result2);
}
}
// The example displays the following output:
// .2 * 10: 2
// .2 Added 10 times: 2.00000024
Module Example
Public Sub Main()
Dim value As Single = .2
Dim result1 As Single = value * 10
Dim result2 As Single
For ctr As Integer = 1 To 10
result2 += value
Next
Console.WriteLine(".2 * 10: {0:R}", result1)
Console.WriteLine(".2 Added 10 times: {0:R}", result2)
End Sub
End Module
' The example displays the following output:
' .2 * 10: 2
' .2 Added 10 times: 2.00000024
Поскольку некоторые числа не могут быть представлены в виде дробных двоичных значений, числа с плавающей запятой могут быть приблизительными только вещественными числами.
Все числа с плавающей запятой имеют ограниченное число значащих цифр, что также определяет, насколько точное значение числа с плавающей запятой приблизительно равно вещественному числу. SingleЗначение имеет длину до 7 десятичных разрядов, хотя для внутренних целей поддерживается не более 9 цифр. Это означает, что некоторые операции с плавающей запятой могут не иметь точности изменять значение с плавающей запятой. В следующем примере определяется большое значение с плавающей запятой одиночной точности, а затем к нему добавляется Single.Epsilon и один квадриллион. Однако продукт слишком мал для изменения исходного значения с плавающей запятой. Его минимальная значимая цифра состоит из тысяч, в то время как наиболее значимая цифра в продукте составляет 10– 30.
using System;
public class Example
{
public static void Main()
{
Single value = 123.456f;
Single additional = Single.Epsilon * 1e15f;
Console.WriteLine($"{value} + {additional} = {value + additional}");
}
}
// The example displays the following output:
// 123.456 + 1.401298E-30 = 123.456
Module Example
Public Sub Main()
Dim value As Single = 123.456
Dim additional As Single = Single.Epsilon * 1e15
Console.WriteLine($"{value} + {additional} = {value + additional}")
End Sub
End Module
' The example displays the following output:
' 123.456 + 1.401298E-30 = 123.456
Ограниченная точность числа с плавающей запятой имеет несколько последствий:
Два числа с плавающей запятой, которые могут казаться равными при определенной точности, на самом деле отличаются, поскольку их менее значащие цифры различаются. В следующем примере ряд чисел добавляется вместе, а их итог сравнивается с ожидаемым итогом. Хотя два значения выглядят одинаково, вызов
Equals
метода указывает, что они не являются.using System; public class Example { public static void Main() { Single[] values = { 10.01f, 2.88f, 2.88f, 2.88f, 9.0f }; Single result = 27.65f; Single total = 0f; foreach (var value in values) total += value; if (total.Equals(result)) Console.WriteLine("The sum of the values equals the total."); else Console.WriteLine("The sum of the values ({0}) does not equal the total ({1}).", total, result); } } // The example displays the following output: // The sum of the values (27.65) does not equal the total (27.65). // // If the index items in the Console.WriteLine statement are changed to {0:R}, // the example displays the following output: // The sum of the values (27.6500015) does not equal the total (27.65).
Module Example Public Sub Main() Dim values() As Single = { 10.01, 2.88, 2.88, 2.88, 9.0 } Dim result As Single = 27.65 Dim total As Single For Each value In values total += value Next If total.Equals(result) Then Console.WriteLine("The sum of the values equals the total.") Else Console.WriteLine("The sum of the values ({0}) does not equal the total ({1}).", total, result) End If End Sub End Module ' The example displays the following output: ' The sum of the values (27.65) does not equal the total (27.65). ' ' If the index items in the Console.WriteLine statement are changed to {0:R}, ' the example displays the following output: ' The sum of the values (27.639999999999997) does not equal the total (27.64).
Если изменить элементы форматирования в Console.WriteLine(String, Object, Object) инструкции с
{0}
и{1}
на{0:R}
и,{1:R}
чтобы отобразить все значащие цифры двух Single значений, то ясно, что эти два значения не равны из-за потери точности во время операций сложения. В этом случае проблему можно устранить, вызвав Math.Round(Double, Int32) метод, чтобы округлить Single значения до нужной точности перед выполнением сравнения.Математическая операция OR, использующая число с плавающей запятой, может не дать одинакового результата, если используется десятичное число, так как число двоичных с плавающей запятой может не совпадать с десятичным числом. Предыдущий пример демонстрирует это, отображая результат умножения 3 на 10 и добавляя 3 в. 3 9 раз.
Если точность числовых операций с дробными значениями важна, используйте Decimal тип вместо Single типа. Если точность числовых операций с целочисленными значениями вне диапазона Int64 UInt64 типов или важна, используйте BigInteger тип.
Значение может не циклически передавалться, если используется число с плавающей запятой. Значение говорит о круговой передаче, если операция преобразует исходное число с плавающей запятой в другую форму, операция обратного преобразования преобразует преобразованную форму обратно в число с плавающей запятой, а окончательное число с плавающей запятой равно исходному числу с плавающей запятой. Цикл обработки может завершиться ошибкой, поскольку одна или несколько наименьших значащих цифр теряются или изменяются при преобразовании. В следующем примере три Single значения преобразуются в строки и сохраняются в файле. Как видно из выходных данных, хотя значения выглядят одинаковыми, восстановленные значения не равны исходным значениям.
using System; using System.IO; public class Example { public static void Main() { StreamWriter sw = new StreamWriter(@".\Singles.dat"); Single[] values = { 3.2f/1.11f, 1.0f/3f, (float) Math.PI }; for (int ctr = 0; ctr < values.Length; ctr++) { sw.Write(values[ctr].ToString()); if (ctr != values.Length - 1) sw.Write("|"); } sw.Close(); Single[] restoredValues = new Single[values.Length]; StreamReader sr = new StreamReader(@".\Singles.dat"); string temp = sr.ReadToEnd(); string[] tempStrings = temp.Split('|'); for (int ctr = 0; ctr < tempStrings.Length; ctr++) restoredValues[ctr] = Single.Parse(tempStrings[ctr]); for (int ctr = 0; ctr < values.Length; ctr++) Console.WriteLine("{0} {2} {1}", values[ctr], restoredValues[ctr], values[ctr].Equals(restoredValues[ctr]) ? "=" : "<>"); } } // The example displays the following output: // 2.882883 <> 2.882883 // 0.3333333 <> 0.3333333 // 3.141593 <> 3.141593
Imports System.IO Module Example Public Sub Main() Dim sw As New StreamWriter(".\Singles.dat") Dim values() As Single = { 3.2/1.11, 1.0/3, CSng(Math.PI) } For ctr As Integer = 0 To values.Length - 1 sw.Write(values(ctr).ToString()) If ctr <> values.Length - 1 Then sw.Write("|") Next sw.Close() Dim restoredValues(values.Length - 1) As Single Dim sr As New StreamReader(".\Singles.dat") Dim temp As String = sr.ReadToEnd() Dim tempStrings() As String = temp.Split("|"c) For ctr As Integer = 0 To tempStrings.Length - 1 restoredValues(ctr) = Single.Parse(tempStrings(ctr)) Next For ctr As Integer = 0 To values.Length - 1 Console.WriteLine("{0} {2} {1}", values(ctr), restoredValues(ctr), If(values(ctr).Equals(restoredValues(ctr)), "=", "<>")) Next End Sub End Module ' The example displays the following output: ' 2.882883 <> 2.882883 ' 0.3333333 <> 0.3333333 ' 3.141593 <> 3.141593
В этом случае можно успешно выполнить циклический обмен значениями, используя стандартную строку числового формата "G9" для сохранения полной точности Single значений, как показано в следующем примере.
using System; using System.IO; public class Example { public static void Main() { StreamWriter sw = new StreamWriter(@".\Singles.dat"); Single[] values = { 3.2f/1.11f, 1.0f/3f, (float) Math.PI }; for (int ctr = 0; ctr < values.Length; ctr++) sw.Write("{0:G9}{1}", values[ctr], ctr < values.Length - 1 ? "|" : "" ); sw.Close(); Single[] restoredValues = new Single[values.Length]; StreamReader sr = new StreamReader(@".\Singles.dat"); string temp = sr.ReadToEnd(); string[] tempStrings = temp.Split('|'); for (int ctr = 0; ctr < tempStrings.Length; ctr++) restoredValues[ctr] = Single.Parse(tempStrings[ctr]); for (int ctr = 0; ctr < values.Length; ctr++) Console.WriteLine("{0} {2} {1}", values[ctr], restoredValues[ctr], values[ctr].Equals(restoredValues[ctr]) ? "=" : "<>"); } } // The example displays the following output: // 2.882883 = 2.882883 // 0.3333333 = 0.3333333 // 3.141593 = 3.141593
Imports System.IO Module Example Public Sub Main() Dim sw As New StreamWriter(".\Singles.dat") Dim values() As Single = { 3.2/1.11, 1.0/3, CSng(Math.PI) } For ctr As Integer = 0 To values.Length - 1 sw.Write("{0:G9}{1}", values(ctr), If(ctr < values.Length - 1, "|", "")) Next sw.Close() Dim restoredValues(values.Length - 1) As Single Dim sr As New StreamReader(".\Singles.dat") Dim temp As String = sr.ReadToEnd() Dim tempStrings() As String = temp.Split("|"c) For ctr As Integer = 0 To tempStrings.Length - 1 restoredValues(ctr) = Single.Parse(tempStrings(ctr)) Next For ctr As Integer = 0 To values.Length - 1 Console.WriteLine("{0} {2} {1}", values(ctr), restoredValues(ctr), If(values(ctr).Equals(restoredValues(ctr)), "=", "<>")) Next End Sub End Module ' The example displays the following output: ' 2.882883 = 2.882883 ' 0.3333333 = 0.3333333 ' 3.141593 = 3.141593
Single значения имеют меньшую точность, чем Double значения. SingleЗначение, которое преобразуется в эквивалентный, Double часто не равно Double значению из-за различий в точности. В следующем примере результат идентичных операций деления присваивается Double значению и Single значению. После Single приведения значения к типу Double , сравнение двух значений показывает, что они не равны.
using System; public class Example { public static void Main() { Double value1 = 1/3.0; Single sValue2 = 1/3.0f; Double value2 = (Double) sValue2; Console.WriteLine("{0:R} = {1:R}: {2}", value1, value2, value1.Equals(value2)); } } // The example displays the following output: // 0.33333333333333331 = 0.3333333432674408: False
Module Example Public Sub Main() Dim value1 As Double = 1/3 Dim sValue2 As Single = 1/3 Dim value2 As Double = CDbl(sValue2) Console.WriteLine("{0} = {1}: {2}", value1, value2, value1.Equals(value2)) End Sub End Module ' The example displays the following output: ' 0.33333333333333331 = 0.3333333432674408: False
Чтобы избежать этой проблемы, либо используйте Double тип данных вместо Single типа данных, либо используйте Round метод, чтобы оба значения имели одинаковую точность.
Проверка на равенство
Чтобы считаться равными, два Single значения должны представлять одинаковые значения. Однако из-за различия в точности между значениями или из-за потери точности по одному или обоим значениям значения с плавающей запятой, которые должны быть идентичными, часто оказываются неравными в связи с различиями в их минимально значащих цифрах. В результате вызовы Equals метода для определения того, равны ли два значения, или вызовы CompareTo метода для определения связи между двумя Single значениями, часто дают непредвиденные результаты. Это очевидно в следующем примере, где два очевидных значения могут Single быть неравными, так как первое значение имеет 7 цифр точности, а второе значение равно 9.
using System;
public class Example
{
public static void Main()
{
float value1 = .3333333f;
float value2 = 1.0f/3;
Console.WriteLine("{0:R} = {1:R}: {2}", value1, value2, value1.Equals(value2));
}
}
// The example displays the following output:
// 0.3333333 = 0.333333343: False
Module Example
Public Sub Main()
Dim value1 As Single = .3333333
Dim value2 As Single = 1/3
Console.WriteLine("{0:R} = {1:R}: {2}", value1, value2, value1.Equals(value2))
End Sub
End Module
' The example displays the following output:
' 0.3333333 = 0.333333343: False
Вычисляемые значения, которые следуют разным путям кода и управляются разными способами, часто не считаются равными. В следующем примере одно Single значение помещается в квадрат, а затем вычисляется квадратный корень для восстановления исходного значения. Вторая Single умножается на 3,51 и в квадрате, прежде чем квадратный корень результата делится на 3,51 для восстановления исходного значения. Несмотря на то, что два значения выглядят одинаковыми, вызов Equals(Single) метода указывает, что они не равны. Использование строки стандартного формата "G9" для возврата результирующей строки, отображающей все значащие цифры каждого Single значения, показывает, что второе значение .0000000000001 меньше первого.
using System;
public class Example
{
public static void Main()
{
float value1 = 10.201438f;
value1 = (float) Math.Sqrt((float) Math.Pow(value1, 2));
float value2 = (float) Math.Pow((float) value1 * 3.51f, 2);
value2 = ((float) Math.Sqrt(value2)) / 3.51f;
Console.WriteLine("{0} = {1}: {2}\n",
value1, value2, value1.Equals(value2));
Console.WriteLine("{0:G9} = {1:G9}", value1, value2);
}
}
// The example displays the following output:
// 10.20144 = 10.20144: False
//
// 10.201438 = 10.2014389
Module Example
Public Sub Main()
Dim value1 As Single = 10.201438
value1 = CSng(Math.Sqrt(CSng(Math.Pow(value1, 2))))
Dim value2 As Single = CSng(Math.Pow(value1 * CSng(3.51), 2))
value2 = CSng(Math.Sqrt(value2) / CSng(3.51))
Console.WriteLine("{0} = {1}: {2}",
value1, value2, value1.Equals(value2))
Console.WriteLine()
Console.WriteLine("{0:G9} = {1:G9}", value1, value2)
End Sub
End Module
' The example displays the following output:
' 10.20144 = 10.20144: False
'
' 10.201438 = 10.2014389
В случаях, когда вероятность потери точности может повлиять на результат сравнения, вместо вызова метода или можно использовать следующие методы Equals CompareTo :
Вызовите Math.Round метод, чтобы убедиться, что оба значения имеют одинаковую точность. Следующий пример изменяет предыдущий пример, чтобы использовать этот подход, чтобы два дробных значения были эквивалентными.
using System; public class Example { public static void Main() { float value1 = .3333333f; float value2 = 1.0f/3; int precision = 7; value1 = (float) Math.Round(value1, precision); value2 = (float) Math.Round(value2, precision); Console.WriteLine("{0:R} = {1:R}: {2}", value1, value2, value1.Equals(value2)); } } // The example displays the following output: // 0.3333333 = 0.3333333: True
Module Example Public Sub Main() Dim value1 As Single = .3333333 Dim value2 As Single = 1/3 Dim precision As Integer = 7 value1 = CSng(Math.Round(value1, precision)) value2 = CSng(Math.Round(value2, precision)) Console.WriteLine("{0:R} = {1:R}: {2}", value1, value2, value1.Equals(value2)) End Sub End Module ' The example displays the following output: ' 0.3333333 = 0.3333333: True
Проблема точности по-прежнему применима к округлению средних значений. Дополнительные сведения см. в описании метода Math.Round(Double, Int32, MidpointRounding).
Проверка на приблизительную равенство вместо равенства. Для этого способа необходимо определить абсолютное значение, по которому два значения могут различаться, но по-прежнему быть равными, или определить относительный объем, на который меньшее значение может отличаться от большего.
Предупреждение
Single.Epsilon иногда используется в качестве абсолютной меры расстояния между двумя Single значениями при проверке на равенство. Однако Single.Epsilon измеряет наименьшее возможное значение, которое можно добавить или вычесть из, Single значение которого равно нулю. Для большинства положительных и отрицательных Single значений значение Single.Epsilon слишком мало для обнаружения. Таким образом, за исключением нулевых значений, не рекомендуется использовать его в тестах на равенство.
В следующем примере используется второй подход для определения
IsApproximatelyEqual
метода, который проверяет относительное различие между двумя значениями. Он также отличается от результата вызововIsApproximatelyEqual
метода и Equals(Single) метода.using System; public class Example { public static void Main() { float one1 = .1f * 10; float one2 = 0f; for (int ctr = 1; ctr <= 10; ctr++) one2 += .1f; Console.WriteLine("{0:R} = {1:R}: {2}", one1, one2, one1.Equals(one2)); Console.WriteLine("{0:R} is approximately equal to {1:R}: {2}", one1, one2, IsApproximatelyEqual(one1, one2, .000001f)); } static bool IsApproximatelyEqual(float value1, float value2, float epsilon) { // If they are equal anyway, just return True. if (value1.Equals(value2)) return true; // Handle NaN, Infinity. if (Double.IsInfinity(value1) | Double.IsNaN(value1)) return value1.Equals(value2); else if (Double.IsInfinity(value2) | Double.IsNaN(value2)) return value1.Equals(value2); // Handle zero to avoid division by zero double divisor = Math.Max(value1, value2); if (divisor.Equals(0)) divisor = Math.Min(value1, value2); return Math.Abs(value1 - value2)/divisor <= epsilon; } } // The example displays the following output: // 1 = 1.00000012: False // 1 is approximately equal to 1.00000012: True
Module Example Public Sub Main() Dim one1 As Single = .1 * 10 Dim one2 As Single = 0 For ctr As Integer = 1 To 10 one2 += CSng(.1) Next Console.WriteLine("{0:R} = {1:R}: {2}", one1, one2, one1.Equals(one2)) Console.WriteLine("{0:R} is approximately equal to {1:R}: {2}", one1, one2, IsApproximatelyEqual(one1, one2, .000001)) End Sub Function IsApproximatelyEqual(value1 As Single, value2 As Single, epsilon As Single) As Boolean ' If they are equal anyway, just return True. If value1.Equals(value2) Then Return True ' Handle NaN, Infinity. If Single.IsInfinity(value1) Or Single.IsNaN(value1) Then Return value1.Equals(value2) Else If Single.IsInfinity(value2) Or Single.IsNaN(value2) Return value1.Equals(value2) End If ' Handle zero to avoid division by zero Dim divisor As Single = Math.Max(value1, value2) If divisor.Equals(0) Then divisor = Math.Min(value1, value2) End If Return Math.Abs(value1 - value2)/divisor <= epsilon End Function End Module ' The example displays the following output: ' 1 = 1.00000012: False ' 1 is approximately equal to 1.00000012: True
Значения и исключения с плавающей запятой
Операции с значениями с плавающей запятой не создают исключения, в отличие от операций с целочисленными типами, которые создают исключения в случае недопустимых операций, таких как деление на ноль или переполнение. Вместо этого в таких ситуациях результат операции с плавающей запятой равен нулю, плюс бесконечность, отрицательная бесконечность или не является числом (NaN):
Если результат операции с плавающей запятой слишком мал для конечного формата, результат равен нулю. Это может произойти при умножении двух очень маленьких чисел с плавающей запятой, как показано в следующем примере.
using System; public class Example { public static void Main() { float value1 = 1.163287e-36f; float value2 = 9.164234e-25f; float result = value1 * value2; Console.WriteLine("{0} * {1} = {2}", value1, value2, result); Console.WriteLine("{0} = 0: {1}", result, result.Equals(0.0f)); } } // The example displays the following output: // 1.163287E-36 * 9.164234E-25 = 0 // 0 = 0: True
Module Example Public Sub Main() Dim value1 As Single = 1.163287e-36 Dim value2 As Single = 9.164234e-25 Dim result As Single = value1 * value2 Console.WriteLine("{0} * {1} = {2:R}", value1, value2, result) Console.WriteLine("{0} = 0: {1}", result, result.Equals(0)) End Sub End Module ' The example displays the following output: ' 1.163287E-36 * 9.164234E-25 = 0 ' 0 = 0: True
Если величина результата операции с плавающей запятой превышает диапазон формата назначения, результатом операции будет PositiveInfinity или NegativeInfinity , в зависимости от знака результата. Результатом операции, которая переполняется Single.MaxValue PositiveInfinity , является, а результатом операции, которая переполняется, Single.MinValue является NegativeInfinity , как показано в следующем примере.
using System; public class Example { public static void Main() { float value1 = 3.065e35f; float value2 = 6.9375e32f; float result = value1 * value2; Console.WriteLine("PositiveInfinity: {0}", Single.IsPositiveInfinity(result)); Console.WriteLine("NegativeInfinity: {0}\n", Single.IsNegativeInfinity(result)); value1 = -value1; result = value1 * value2; Console.WriteLine("PositiveInfinity: {0}", Single.IsPositiveInfinity(result)); Console.WriteLine("NegativeInfinity: {0}", Single.IsNegativeInfinity(result)); } } // The example displays the following output: // PositiveInfinity: True // NegativeInfinity: False // // PositiveInfinity: False // NegativeInfinity: True
Module Example Public Sub Main() Dim value1 As Single = 3.065e35 Dim value2 As Single = 6.9375e32 Dim result As Single = value1 * value2 Console.WriteLine("PositiveInfinity: {0}", Single.IsPositiveInfinity(result)) Console.WriteLine("NegativeInfinity: {0}", Single.IsNegativeInfinity(result)) Console.WriteLine() value1 = -value1 result = value1 * value2 Console.WriteLine("PositiveInfinity: {0}", Single.IsPositiveInfinity(result)) Console.WriteLine("NegativeInfinity: {0}", Single.IsNegativeInfinity(result)) End Sub End Module ' The example displays the following output: ' PositiveInfinity: True ' NegativeInfinity: False ' ' PositiveInfinity: False ' NegativeInfinity: True
PositiveInfinity также результаты из деления на ноль с положительным делимым и NegativeInfinity результатом деления на ноль с отрицательным делимым.
Если операция с плавающей запятой является недопустимой, результатом операции будет NaN . Например, NaN результаты выполнения следующих операций:
Деление на ноль с делимым на ноль. Обратите внимание, что другие варианты деления на ноль приводят к одному PositiveInfinity или NegativeInfinity .
Любая операция с плавающей запятой с недопустимыми входными данными. Например, при попытке найти квадратный корень из отрицательного значения возвращается значение NaN .
Любая операция с аргументом, значение которого равно Single.NaN .
Преобразования типов и единая структура
В Single структуре не определены явные или неявные операторы преобразования. вместо этого преобразования реализуются компилятором.
В следующей таблице перечислены возможные преобразования значения других примитивных числовых типов в Single значение, а также указывает, является ли преобразование расширяющимся или сужающим, и может ли результирующий объект Single иметь меньшую точность, чем исходное значение.
Допустимо ли преобразование из | Расширяющие и узкие | Возможная потери точности |
---|---|---|
Byte | Widening | Нет |
Decimal | Widening Обратите внимание, что в C# требуется оператор CAST. |
Да. Decimal поддерживает 29 десятичных разрядов точности; Single поддерживает 9. |
Double | Сужающие значения вне диапазона преобразуются в Double.NegativeInfinity или Double.PositiveInfinity . | Да. Double поддерживает 17 десятичных разрядов точности; Single поддерживает 9. |
Int16 | Widening | Нет |
Int32 | Widening | Да. Int32 поддерживает 10 десятичных разрядов точности; Single поддерживает 9. |
Int64 | Widening | Да. Int64 поддерживает 19 десятичных разрядов точности; Single поддерживает 9. |
SByte | Widening | Нет |
UInt16 | Widening | Нет |
UInt32 | Widening | Да. UInt32 поддерживает 10 десятичных разрядов точности; Single поддерживает 9. |
UInt64 | Widening | Да. Int64 поддерживает 20 десятичных разрядов точности; Single поддерживает 9. |
В следующем примере минимальное или максимальное значение других примитивных числовых типов преобразуется в Single значение.
using System;
public class Example
{
public static void Main()
{
dynamic[] values = { Byte.MinValue, Byte.MaxValue, Decimal.MinValue,
Decimal.MaxValue, Double.MinValue, Double.MaxValue,
Int16.MinValue, Int16.MaxValue, Int32.MinValue,
Int32.MaxValue, Int64.MinValue, Int64.MaxValue,
SByte.MinValue, SByte.MaxValue, UInt16.MinValue,
UInt16.MaxValue, UInt32.MinValue, UInt32.MaxValue,
UInt64.MinValue, UInt64.MaxValue };
float sngValue;
foreach (var value in values) {
if (value.GetType() == typeof(Decimal) ||
value.GetType() == typeof(Double))
sngValue = (float) value;
else
sngValue = value;
Console.WriteLine("{0} ({1}) --> {2:R} ({3})",
value, value.GetType().Name,
sngValue, sngValue.GetType().Name);
}
}
}
// The example displays the following output:
// 0 (Byte) --> 0 (Single)
// 255 (Byte) --> 255 (Single)
// -79228162514264337593543950335 (Decimal) --> -7.92281625E+28 (Single)
// 79228162514264337593543950335 (Decimal) --> 7.92281625E+28 (Single)
// -1.79769313486232E+308 (Double) --> -Infinity (Single)
// 1.79769313486232E+308 (Double) --> Infinity (Single)
// -32768 (Int16) --> -32768 (Single)
// 32767 (Int16) --> 32767 (Single)
// -2147483648 (Int32) --> -2.14748365E+09 (Single)
// 2147483647 (Int32) --> 2.14748365E+09 (Single)
// -9223372036854775808 (Int64) --> -9.223372E+18 (Single)
// 9223372036854775807 (Int64) --> 9.223372E+18 (Single)
// -128 (SByte) --> -128 (Single)
// 127 (SByte) --> 127 (Single)
// 0 (UInt16) --> 0 (Single)
// 65535 (UInt16) --> 65535 (Single)
// 0 (UInt32) --> 0 (Single)
// 4294967295 (UInt32) --> 4.2949673E+09 (Single)
// 0 (UInt64) --> 0 (Single)
// 18446744073709551615 (UInt64) --> 1.84467441E+19 (Single)
Module Example
Public Sub Main()
Dim values() As Object = { Byte.MinValue, Byte.MaxValue, Decimal.MinValue,
Decimal.MaxValue, Double.MinValue, Double.MaxValue,
Int16.MinValue, Int16.MaxValue, Int32.MinValue,
Int32.MaxValue, Int64.MinValue, Int64.MaxValue,
SByte.MinValue, SByte.MaxValue, UInt16.MinValue,
UInt16.MaxValue, UInt32.MinValue, UInt32.MaxValue,
UInt64.MinValue, UInt64.MaxValue }
Dim sngValue As Single
For Each value In values
If value.GetType() = GetType(Double) Then
sngValue = CSng(value)
Else
sngValue = value
End If
Console.WriteLine("{0} ({1}) --> {2:R} ({3})",
value, value.GetType().Name,
sngValue, sngValue.GetType().Name)
Next
End Sub
End Module
' The example displays the following output:
' 0 (Byte) --> 0 (Single)
' 255 (Byte) --> 255 (Single)
' -79228162514264337593543950335 (Decimal) --> -7.92281625E+28 (Single)
' 79228162514264337593543950335 (Decimal) --> 7.92281625E+28 (Single)
' -1.79769313486232E+308 (Double) --> -Infinity (Single)
' 1.79769313486232E+308 (Double) --> Infinity (Single)
' -32768 (Int16) --> -32768 (Single)
' 32767 (Int16) --> 32767 (Single)
' -2147483648 (Int32) --> -2.14748365E+09 (Single)
' 2147483647 (Int32) --> 2.14748365E+09 (Single)
' -9223372036854775808 (Int64) --> -9.223372E+18 (Single)
' 9223372036854775807 (Int64) --> 9.223372E+18 (Single)
' -128 (SByte) --> -128 (Single)
' 127 (SByte) --> 127 (Single)
' 0 (UInt16) --> 0 (Single)
' 65535 (UInt16) --> 65535 (Single)
' 0 (UInt32) --> 0 (Single)
' 4294967295 (UInt32) --> 4.2949673E+09 (Single)
' 0 (UInt64) --> 0 (Single)
' 18446744073709551615 (UInt64) --> 1.84467441E+19 (Single)
Кроме того, Double значения, Double.NaN Double.PositiveInfinity и Double.NegativeInfinity преобразуются в Single.NaN , Single.PositiveInfinity и Single.NegativeInfinity соответственно.
Обратите внимание, что преобразование значения некоторых числовых типов в Single значение может привести к утрате точности. Как показано в примере, возможна утрата точности при преобразовании значений,,,, Decimal Double Int32 Int64 UInt32 и UInt64 в Single значения.
Преобразование Single значения в Double является расширяющим преобразованием. Преобразование может привести к утрате точности, если тип не Double имеет точного представления Single значения.
Преобразование Single значения в значение любого типа данных-примитива, отличного от, представляет собой Double понижающие преобразования и требует оператора приведения (в C#) или метода преобразования (в Visual Basic). Значения, находящиеся за пределами диапазона целевого типа данных, определяемые MinValue
свойствами и свойств целевого типа MaxValue
, ведут себя так, как показано в следующей таблице.
Тип результирующего значения | Результат |
---|---|
Любой целочисленный тип | OverflowExceptionИсключение, если преобразование происходит в проверяемом контексте. Если преобразование происходит в непроверяемом контексте (по умолчанию в C#), операция преобразования выполняется успешно, но значение переполняется. |
Decimal | OverflowExceptionИсключение, |
Кроме того, Single.NaN , Single.PositiveInfinity и Single.NegativeInfinity вызывают OverflowException для преобразования в целые числа в проверяемом контексте, но эти значения переполняются при преобразовании в целые числа в непроверяемом контексте. Для преобразований Decimal они всегда создают исключение OverflowException . Для преобразований Double они преобразуют в Double.NaN , Double.PositiveInfinity и Double.NegativeInfinity соответственно.
Обратите внимание, что при преобразовании Single значения в другой числовой тип может произойти утрата точности. в случае преобразования нецелочисленных Single значений, как показано в выходных данных примера, дробный компонент теряется, если Single значение округляется (как в Visual Basic) или усекается (как в C#). Для преобразований в Decimal значения Single значение может не иметь точного представления в целевом типе данных.
В следующем примере число значений преобразуется Single в несколько других числовых типов. преобразования выполняются в проверяемом контексте в Visual Basic (по умолчанию) и в C# (из-за ключевого слова checked ). Выходные данные в примере показывают результат для преобразований в проверяемом непроверяемом контексте. вы можете выполнять преобразования в непроверенном контексте в Visual Basic путем компиляции с помощью /removeintchecks+
параметра компилятора и в C#, закомментируя checked
инструкцию.
using System;
public class Example
{
public static void Main()
{
float[] values = { Single.MinValue, -67890.1234f, -12345.6789f,
12345.6789f, 67890.1234f, Single.MaxValue,
Single.NaN, Single.PositiveInfinity,
Single.NegativeInfinity };
checked {
foreach (var value in values) {
try {
Int64 lValue = (long) value;
Console.WriteLine("{0} ({1}) --> {2} (0x{2:X16}) ({3})",
value, value.GetType().Name,
lValue, lValue.GetType().Name);
}
catch (OverflowException) {
Console.WriteLine("Unable to convert {0} to Int64.", value);
}
try {
UInt64 ulValue = (ulong) value;
Console.WriteLine("{0} ({1}) --> {2} (0x{2:X16}) ({3})",
value, value.GetType().Name,
ulValue, ulValue.GetType().Name);
}
catch (OverflowException) {
Console.WriteLine("Unable to convert {0} to UInt64.", value);
}
try {
Decimal dValue = (decimal) value;
Console.WriteLine("{0} ({1}) --> {2} ({3})",
value, value.GetType().Name,
dValue, dValue.GetType().Name);
}
catch (OverflowException) {
Console.WriteLine("Unable to convert {0} to Decimal.", value);
}
Double dblValue = value;
Console.WriteLine("{0} ({1}) --> {2} ({3})",
value, value.GetType().Name,
dblValue, dblValue.GetType().Name);
Console.WriteLine();
}
}
}
}
// The example displays the following output for conversions performed
// in a checked context:
// Unable to convert -3.402823E+38 to Int64.
// Unable to convert -3.402823E+38 to UInt64.
// Unable to convert -3.402823E+38 to Decimal.
// -3.402823E+38 (Single) --> -3.40282346638529E+38 (Double)
//
// -67890.13 (Single) --> -67890 (0xFFFFFFFFFFFEF6CE) (Int64)
// Unable to convert -67890.13 to UInt64.
// -67890.13 (Single) --> -67890.12 (Decimal)
// -67890.13 (Single) --> -67890.125 (Double)
//
// -12345.68 (Single) --> -12345 (0xFFFFFFFFFFFFCFC7) (Int64)
// Unable to convert -12345.68 to UInt64.
// -12345.68 (Single) --> -12345.68 (Decimal)
// -12345.68 (Single) --> -12345.6787109375 (Double)
//
// 12345.68 (Single) --> 12345 (0x0000000000003039) (Int64)
// 12345.68 (Single) --> 12345 (0x0000000000003039) (UInt64)
// 12345.68 (Single) --> 12345.68 (Decimal)
// 12345.68 (Single) --> 12345.6787109375 (Double)
//
// 67890.13 (Single) --> 67890 (0x0000000000010932) (Int64)
// 67890.13 (Single) --> 67890 (0x0000000000010932) (UInt64)
// 67890.13 (Single) --> 67890.12 (Decimal)
// 67890.13 (Single) --> 67890.125 (Double)
//
// Unable to convert 3.402823E+38 to Int64.
// Unable to convert 3.402823E+38 to UInt64.
// Unable to convert 3.402823E+38 to Decimal.
// 3.402823E+38 (Single) --> 3.40282346638529E+38 (Double)
//
// Unable to convert NaN to Int64.
// Unable to convert NaN to UInt64.
// Unable to convert NaN to Decimal.
// NaN (Single) --> NaN (Double)
//
// Unable to convert Infinity to Int64.
// Unable to convert Infinity to UInt64.
// Unable to convert Infinity to Decimal.
// Infinity (Single) --> Infinity (Double)
//
// Unable to convert -Infinity to Int64.
// Unable to convert -Infinity to UInt64.
// Unable to convert -Infinity to Decimal.
// -Infinity (Single) --> -Infinity (Double)
// The example displays the following output for conversions performed
// in an unchecked context:
// -3.402823E+38 (Single) --> -9223372036854775808 (0x8000000000000000) (Int64)
// -3.402823E+38 (Single) --> 9223372036854775808 (0x8000000000000000) (UInt64)
// Unable to convert -3.402823E+38 to Decimal.
// -3.402823E+38 (Single) --> -3.40282346638529E+38 (Double)
//
// -67890.13 (Single) --> -67890 (0xFFFFFFFFFFFEF6CE) (Int64)
// -67890.13 (Single) --> 18446744073709483726 (0xFFFFFFFFFFFEF6CE) (UInt64)
// -67890.13 (Single) --> -67890.12 (Decimal)
// -67890.13 (Single) --> -67890.125 (Double)
//
// -12345.68 (Single) --> -12345 (0xFFFFFFFFFFFFCFC7) (Int64)
// -12345.68 (Single) --> 18446744073709539271 (0xFFFFFFFFFFFFCFC7) (UInt64)
// -12345.68 (Single) --> -12345.68 (Decimal)
// -12345.68 (Single) --> -12345.6787109375 (Double)
//
// 12345.68 (Single) --> 12345 (0x0000000000003039) (Int64)
// 12345.68 (Single) --> 12345 (0x0000000000003039) (UInt64)
// 12345.68 (Single) --> 12345.68 (Decimal)
// 12345.68 (Single) --> 12345.6787109375 (Double)
//
// 67890.13 (Single) --> 67890 (0x0000000000010932) (Int64)
// 67890.13 (Single) --> 67890 (0x0000000000010932) (UInt64)
// 67890.13 (Single) --> 67890.12 (Decimal)
// 67890.13 (Single) --> 67890.125 (Double)
//
// 3.402823E+38 (Single) --> -9223372036854775808 (0x8000000000000000) (Int64)
// 3.402823E+38 (Single) --> 0 (0x0000000000000000) (UInt64)
// Unable to convert 3.402823E+38 to Decimal.
// 3.402823E+38 (Single) --> 3.40282346638529E+38 (Double)
//
// NaN (Single) --> -9223372036854775808 (0x8000000000000000) (Int64)
// NaN (Single) --> 0 (0x0000000000000000) (UInt64)
// Unable to convert NaN to Decimal.
// NaN (Single) --> NaN (Double)
//
// Infinity (Single) --> -9223372036854775808 (0x8000000000000000) (Int64)
// Infinity (Single) --> 0 (0x0000000000000000) (UInt64)
// Unable to convert Infinity to Decimal.
// Infinity (Single) --> Infinity (Double)
//
// -Infinity (Single) --> -9223372036854775808 (0x8000000000000000) (Int64)
// -Infinity (Single) --> 9223372036854775808 (0x8000000000000000) (UInt64)
// Unable to convert -Infinity to Decimal.
// -Infinity (Single) --> -Infinity (Double)
Module Example
Public Sub Main()
Dim values() As Single = { Single.MinValue, -67890.1234, -12345.6789,
12345.6789, 67890.1234, Single.MaxValue,
Single.NaN, Single.PositiveInfinity,
Single.NegativeInfinity }
For Each value In values
Try
Dim lValue As Long = CLng(value)
Console.WriteLine("{0} ({1}) --> {2} (0x{2:X16}) ({3})",
value, value.GetType().Name,
lValue, lValue.GetType().Name)
Catch e As OverflowException
Console.WriteLine("Unable to convert {0} to Int64.", value)
End Try
Try
Dim ulValue As UInt64 = CULng(value)
Console.WriteLine("{0} ({1}) --> {2} (0x{2:X16}) ({3})",
value, value.GetType().Name,
ulValue, ulValue.GetType().Name)
Catch e As OverflowException
Console.WriteLine("Unable to convert {0} to UInt64.", value)
End Try
Try
Dim dValue As Decimal = CDec(value)
Console.WriteLine("{0} ({1}) --> {2} ({3})",
value, value.GetType().Name,
dValue, dValue.GetType().Name)
Catch e As OverflowException
Console.WriteLine("Unable to convert {0} to Decimal.", value)
End Try
Dim dblValue As Double = value
Console.WriteLine("{0} ({1}) --> {2} ({3})",
value, value.GetType().Name,
dblValue, dblValue.GetType().Name)
Console.WriteLine()
Next
End Sub
End Module
' The example displays the following output for conversions performed
' in a checked context:
' Unable to convert -3.402823E+38 to Int64.
' Unable to convert -3.402823E+38 to UInt64.
' Unable to convert -3.402823E+38 to Decimal.
' -3.402823E+38 (Single) --> -3.40282346638529E+38 (Double)
'
' -67890.13 (Single) --> -67890 (0xFFFFFFFFFFFEF6CE) (Int64)
' Unable to convert -67890.13 to UInt64.
' -67890.13 (Single) --> -67890.12 (Decimal)
' -67890.13 (Single) --> -67890.125 (Double)
'
' -12345.68 (Single) --> -12346 (0xFFFFFFFFFFFFCFC6) (Int64)
' Unable to convert -12345.68 to UInt64.
' -12345.68 (Single) --> -12345.68 (Decimal)
' -12345.68 (Single) --> -12345.6787109375 (Double)
'
' 12345.68 (Single) --> 12346 (0x000000000000303A) (Int64)
' 12345.68 (Single) --> 12346 (0x000000000000303A) (UInt64)
' 12345.68 (Single) --> 12345.68 (Decimal)
' 12345.68 (Single) --> 12345.6787109375 (Double)
'
' 67890.13 (Single) --> 67890 (0x0000000000010932) (Int64)
' 67890.13 (Single) --> 67890 (0x0000000000010932) (UInt64)
' 67890.13 (Single) --> 67890.12 (Decimal)
' 67890.13 (Single) --> 67890.125 (Double)
'
' Unable to convert 3.402823E+38 to Int64.
' Unable to convert 3.402823E+38 to UInt64.
' Unable to convert 3.402823E+38 to Decimal.
' 3.402823E+38 (Single) --> 3.40282346638529E+38 (Double)
'
' Unable to convert NaN to Int64.
' Unable to convert NaN to UInt64.
' Unable to convert NaN to Decimal.
' NaN (Single) --> NaN (Double)
'
' Unable to convert Infinity to Int64.
' Unable to convert Infinity to UInt64.
' Unable to convert Infinity to Decimal.
' Infinity (Single) --> Infinity (Double)
'
' Unable to convert -Infinity to Int64.
' Unable to convert -Infinity to UInt64.
' Unable to convert -Infinity to Decimal.
' -Infinity (Single) --> -Infinity (Double)
' The example displays the following output for conversions performed
' in an unchecked context:
' -3.402823E+38 (Single) --> -9223372036854775808 (0x8000000000000000) (Int64)
' -3.402823E+38 (Single) --> 9223372036854775808 (0x8000000000000000) (UInt64)
' Unable to convert -3.402823E+38 to Decimal.
' -3.402823E+38 (Single) --> -3.40282346638529E+38 (Double)
'
' -67890.13 (Single) --> -67890 (0xFFFFFFFFFFFEF6CE) (Int64)
' -67890.13 (Single) --> 18446744073709483726 (0xFFFFFFFFFFFEF6CE) (UInt64)
' -67890.13 (Single) --> -67890.12 (Decimal)
' -67890.13 (Single) --> -67890.125 (Double)
'
' -12345.68 (Single) --> -12346 (0xFFFFFFFFFFFFCFC6) (Int64)
' -12345.68 (Single) --> 18446744073709539270 (0xFFFFFFFFFFFFCFC6) (UInt64)
' -12345.68 (Single) --> -12345.68 (Decimal)
' -12345.68 (Single) --> -12345.6787109375 (Double)
'
' 12345.68 (Single) --> 12346 (0x000000000000303A) (Int64)
' 12345.68 (Single) --> 12346 (0x000000000000303A) (UInt64)
' 12345.68 (Single) --> 12345.68 (Decimal)
' 12345.68 (Single) --> 12345.6787109375 (Double)
'
' 67890.13 (Single) --> 67890 (0x0000000000010932) (Int64)
' 67890.13 (Single) --> 67890 (0x0000000000010932) (UInt64)
' 67890.13 (Single) --> 67890.12 (Decimal)
' 67890.13 (Single) --> 67890.125 (Double)
'
' 3.402823E+38 (Single) --> -9223372036854775808 (0x8000000000000000) (Int64)
' 3.402823E+38 (Single) --> 0 (0x0000000000000000) (UInt64)
' Unable to convert 3.402823E+38 to Decimal.
' 3.402823E+38 (Single) --> 3.40282346638529E+38 (Double)
'
' NaN (Single) --> -9223372036854775808 (0x8000000000000000) (Int64)
' NaN (Single) --> 0 (0x0000000000000000) (UInt64)
' Unable to convert NaN to Decimal.
' NaN (Single) --> NaN (Double)
'
' Infinity (Single) --> -9223372036854775808 (0x8000000000000000) (Int64)
' Infinity (Single) --> 0 (0x0000000000000000) (UInt64)
' Unable to convert Infinity to Decimal.
' Infinity (Single) --> Infinity (Double)
'
' -Infinity (Single) --> -9223372036854775808 (0x8000000000000000) (Int64)
' -Infinity (Single) --> 9223372036854775808 (0x8000000000000000) (UInt64)
' Unable to convert -Infinity to Decimal.
' -Infinity (Single) --> -Infinity (Double)
дополнительные сведения о преобразовании числовых типов см. в разделе преобразование типов в таблицах платформа .NET Framework и преобразования типов.
Функция вычислений с плавающей запятой
SingleСтруктура и связанные типы предоставляют методы для выполнения следующих категорий операций:
Сравнение значений. Можно вызвать метод, Equals чтобы определить Single , равны ли два значения, или CompareTo метод для определения связи между двумя значениями.
SingleСтруктура также поддерживает полный набор операторов сравнения. Например, можно проверить на равенство или неравенство или определить, является ли одно значение больше или равно другому значению. Если один из операндов — Double , Single значение преобразуется в Double перед выполнением сравнения. Если один из операндов является целочисленным типом, Single перед выполнением сравнения он преобразуется в. Хотя это расширяющие преобразования, они могут привести к утрате точности.
Предупреждение
Из-за различий в точности два Single значения, которые должны быть равны, могут быть неравными, что влияет на результат сравнения. Дополнительные сведения о сравнении двух значений см. в разделе Проверка на равенство Single .
IsNaN IsInfinity IsPositiveInfinity IsNegativeInfinity Для проверки этих специальных значений можно также вызвать методы,, и.
Математические операции. Распространенные арифметические операции, такие как сложение, вычитание, умножение и деление, реализуются компиляторами языка и инструкциями на языке CIL, а не Single методами. Если другой операнд в математической операции — Double , Single Double перед выполнением операции преобразуется в, а результатом операции также является Double значение. Если другой операнд является целочисленным типом, он преобразуется в Single перед выполнением операции, а результат операции также является Single значением.
можно выполнять другие математические операции, вызывая
static
Shared
методы (в Visual Basic) в System.Math классе. К ним относятся дополнительные методы, обычно используемые для арифметических операций (например Math.Abs ,, Math.Sign и Math.Sqrt ), Geometry (например, Math.Cos и Math.Sin ) и математического анализа за (например, Math.Log ). Во всех случаях Single значение преобразуется в Double .Можно также манипулировать отдельными битами Single значения. BitConverter.GetBytes(Single)Метод возвращает свой битовый шаблон в массиве байтов. Передавая этот массив байтов в BitConverter.ToInt32 метод, можно также сохранить Single битовый шаблон значения в 32-битовом целом формате.
Округление. Округление часто используется как метод снижения влияния различий между значениями, вызванными проблемами представления и точности с плавающей запятой. Можно округлить Single значение, вызвав Math.Round метод. Однако обратите внимание, что Single значение преобразуется в Double перед вызовом метода, а преобразование может привести к утрате точности.
Форматирование. Значение можно преобразовать Single в строковое представление, вызвав ToString метод или воспользовавшись функцией составного форматирования . Сведения о том, как строки формата управляют строковым представлением значений с плавающей запятой, см. в разделах стандартные строки числовых форматов и строки настраиваемых числовых форматов .
Синтаксический анализ строк. Можно преобразовать строковое представление значения с плавающей запятой в Single значение, вызвав Parse TryParse метод или. Если операция синтаксического анализа завершается неудачно, Parse метод создает исключение, в то время как TryParse метод возвращает
false
.Преобразование типов. Singleструктура предоставляет явную реализацию интерфейса для IConvertible интерфейса, который поддерживает преобразование между любыми двумя стандартными платформа .NET Frameworkными типами данных. Языковые компиляторы также поддерживают неявное преобразование значений для всех других стандартных числовых типов, за исключением преобразования Double в Single значения. Преобразование значения любого стандартного числового типа, отличного от, Double в Single , является расширяющим преобразованием и не требует использования оператора приведения или метода преобразования.
Однако преобразование 32-разрядных и 64-разрядных целочисленных значений может привести к утрате точности. В следующей таблице перечислены различия в точности для 32-разрядных, 64-разрядных и Double типов:
Type Максимальная точность (в десятичных цифрах) Внутренняя точность (в десятичных цифрах) Double 15 17 Int32 и UInt32 10 10 Int64 и UInt64 19 19 Single 7 9 Проблема точности чаще всего влияет на Single значения, которые преобразуются в Double значения. В следующем примере два значения, созданные идентичными операциями деления, не равны, так как одно из значений является значением с плавающей запятой одиночной точности, которое преобразуется в Double .
using System; public class Example { public static void Main() { Double value1 = 1/3.0; Single sValue2 = 1/3.0f; Double value2 = (Double) sValue2; Console.WriteLine("{0:R} = {1:R}: {2}", value1, value2, value1.Equals(value2)); } } // The example displays the following output: // 0.33333333333333331 = 0.3333333432674408: False
Module Example Public Sub Main() Dim value1 As Double = 1/3 Dim sValue2 As Single = 1/3 Dim value2 As Double = CDbl(sValue2) Console.WriteLine("{0} = {1}: {2}", value1, value2, value1.Equals(value2)) End Sub End Module ' The example displays the following output: ' 0.33333333333333331 = 0.3333333432674408: False
Поля
Epsilon |
Представляет наименьшее положительное значение Single больше нуля. Это поле является константой. |
MaxValue |
Представляет наибольшее возможное значение типа Single. Это поле является константой. |
MinValue |
Представляет минимально допустимое значение типа Single. Это поле является константой. |
NaN |
Представляет нечисловое значение ( |
NegativeInfinity |
Представляет минус бесконечность. Это поле является константой. |
PositiveInfinity |
Представляет плюс бесконечность. Это поле является константой. |
Методы
CompareTo(Object) |
Сравнивает данный экземпляр с указанным объектом и возвращает целое число, которое показывает, является ли значение данного экземпляра меньше, больше или равно значению заданного объекта. |
CompareTo(Single) |
Сравнивает данный экземпляр с заданным числом одиночной точности с плавающей запятой и возвращает целое число, которое показывает, является ли значение данного экземпляра меньше, больше или равным значению заданного числа одиночной точности с плавающей запятой. |
Equals(Object) |
Возвращает значение, показывающее, равен ли данный экземпляр заданному объекту. |
Equals(Single) |
Возвращает значение, позволяющее определить, представляют ли этот экземпляр и заданный объект Single одно и то же значение. |
GetHashCode() |
Возвращает хэш-код данного экземпляра. |
GetTypeCode() | |
IsFinite(Single) |
Определяет, является ли указанное значение конечным (нулевым, поднормальным или нормальным). |
IsInfinity(Single) |
Возвращает значение, позволяющее определить, равно ли данное число плюс или минус бесконечности. |
IsNaN(Single) |
Возвращает значение, показывающее, что указанное значение не является числом (NaN). |
IsNegative(Single) |
Определяет, является ли заданное значение отрицательным. |
IsNegativeInfinity(Single) |
Возвращает значение, позволяющее определить, равно ли данное число минус бесконечности. |
IsNormal(Single) |
Определяет, является ли заданное значение нормальным. |
IsPositiveInfinity(Single) |
Возвращает значение, показывающее, равно ли данное число плюс бесконечности. |
IsSubnormal(Single) |
Определяет, является ли заданное значение поднормальным. |
Parse(ReadOnlySpan<Char>, NumberStyles, IFormatProvider) |
Преобразует диапазон символов, содержащий строковое представление числа в указанном стиле и с использованием формата, соответствующего данному языку и региональным параметрам, в эквивалентное ему число одиночной точности с плавающей запятой. |
Parse(String) |
Преобразует строковое представление числа в эквивалентное ему число с плавающей запятой одиночной точности. |
Parse(String, IFormatProvider) |
Преобразует строковое представление числа, записанное в формате, соответствующем определенному языку и региональным параметрам, в эквивалентное ему число одиночной точности с плавающей запятой. |
Parse(String, NumberStyles) |
Преобразует строковое представление числа в указанном стиле в эквивалентное ему число одиночной точности с плавающей запятой. |
Parse(String, NumberStyles, IFormatProvider) |
Преобразует строковое представление числа в указанном стиле и с использованием формата, соответствующего данному языку и региональным параметрам, в эквивалентное ему число с плавающей запятой одиночной точности. |
ToString() |
Преобразует числовое значение данного экземпляра в эквивалентное ему строковое представление. |
ToString(IFormatProvider) |
Преобразует числовое значение данного экземпляра в эквивалентное ему строковое представление с использованием указанных сведений об особенностях форматирования для данного языка и региональных параметров. |
ToString(String) |
Преобразует числовое значение данного экземпляра в эквивалентное строковое представление с использованием указанного формата. |
ToString(String, IFormatProvider) |
Преобразует числовое значение данного экземпляра в эквивалентное ему строковое представление с использованием указанного формата и сведений об особенностях форматирования для данного языка и региональных параметров. |
TryFormat(Span<Char>, Int32, ReadOnlySpan<Char>, IFormatProvider) |
Пытается форматировать значение текущего экземпляра числа с плавающей запятой в указанный диапазон символов. |
TryParse(ReadOnlySpan<Char>, NumberStyles, IFormatProvider, Single) |
Преобразует представление диапазона числа в указанном стиле и с использованием формата, соответствующего данному языку и региональным параметрам, в эквивалентное ему число одиночной точности с плавающей запятой. Возвращает значение, указывающее, успешно ли выполнено преобразование. |
TryParse(ReadOnlySpan<Char>, Single) |
Преобразует строковое представление числа в диапазоне символов в эквивалентное ему число одиночной точности с плавающей запятой. Возвращает значение, указывающее, успешно ли выполнено преобразование. |
TryParse(String, NumberStyles, IFormatProvider, Single) |
Преобразует строковое представление числа в указанном стиле и с использованием формата, соответствующего данному языку и региональным параметрам, в эквивалентное ему число одиночной точности с плавающей запятой. Возвращает значение, указывающее, успешно ли выполнено преобразование. |
TryParse(String, Single) |
Преобразует строковое представление числа в эквивалентное ему число одиночной точности с плавающей запятой. Возвращает значение, указывающее, успешно ли выполнено преобразование. |
Операторы
Equality(Single, Single) |
Возвращает значение, указывающее, равны ли два заданных значения Single. |
GreaterThan(Single, Single) |
Возвращает значение, указывающее, действительно ли заданное значение Single больше другого заданного значения Single. |
GreaterThanOrEqual(Single, Single) |
Возвращает значение, указывающее, действительно ли заданное значение Single больше или равно другому заданному значению Single. |
Inequality(Single, Single) |
Возвращает значение, указывающее, не равны ли два заданных значения Single. |
LessThan(Single, Single) |
Возвращает значение, указывающее, действительно ли заданное значение Single меньше другого заданного значения Single. |
LessThanOrEqual(Single, Single) |
Возвращает значение, указывающее, действительно ли заданное значение Single меньше или равно другому заданному значению Single. |
Явные реализации интерфейса
Применяется к
Потокобезопасность
Все члены этого типа являются потокобезопасными. Члены, которые могут изменить состояние экземпляра, в действительности возвращают новый экземпляр, инициализированный новым значением. Как с любым другим типом, чтение и запись общей переменной, которая содержит экземпляр этого типа, должны быть защищены блокировкой для обеспечения потокобезопасности.