Single Struct
Definizione
Importante
Alcune informazioni sono relative alla release non definitiva del prodotto, che potrebbe subire modifiche significative prima della release definitiva. Microsoft non riconosce alcuna garanzia, espressa o implicita, in merito alle informazioni qui fornite.
Rappresenta un numero a virgola mobile a precisione singola.
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<float>, IConvertible, IEquatable<float>, IParsable<float>, ISpanParsable<float>, System::Numerics::IAdditionOperators<float, float, float>, System::Numerics::IAdditiveIdentity<float, float>, System::Numerics::IBinaryFloatingPointIeee754<float>, System::Numerics::IBinaryNumber<float>, System::Numerics::IBitwiseOperators<float, float, float>, System::Numerics::IComparisonOperators<float, float, bool>, System::Numerics::IDecrementOperators<float>, System::Numerics::IDivisionOperators<float, float, float>, System::Numerics::IEqualityOperators<float, float, bool>, System::Numerics::IExponentialFunctions<float>, System::Numerics::IFloatingPoint<float>, System::Numerics::IFloatingPointConstants<float>, System::Numerics::IFloatingPointIeee754<float>, System::Numerics::IHyperbolicFunctions<float>, System::Numerics::IIncrementOperators<float>, System::Numerics::ILogarithmicFunctions<float>, System::Numerics::IMinMaxValue<float>, System::Numerics::IModulusOperators<float, float, float>, System::Numerics::IMultiplicativeIdentity<float, float>, System::Numerics::IMultiplyOperators<float, float, float>, System::Numerics::INumber<float>, System::Numerics::INumberBase<float>, System::Numerics::IPowerFunctions<float>, System::Numerics::IRootFunctions<float>, System::Numerics::ISignedNumber<float>, System::Numerics::ISubtractionOperators<float, float, float>, System::Numerics::ITrigonometricFunctions<float>, System::Numerics::IUnaryNegationOperators<float, float>, System::Numerics::IUnaryPlusOperators<float, float>
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 readonly struct Single : IComparable, IComparable<float>, IConvertible, IEquatable<float>, IFormattable
public readonly struct Single : IComparable, IComparable<float>, IConvertible, IEquatable<float>, ISpanFormattable
public readonly struct Single : IComparable<float>, IConvertible, IEquatable<float>, IParsable<float>, ISpanParsable<float>, System.Numerics.IAdditionOperators<float,float,float>, System.Numerics.IAdditiveIdentity<float,float>, System.Numerics.IBinaryFloatingPointIeee754<float>, System.Numerics.IBinaryNumber<float>, System.Numerics.IBitwiseOperators<float,float,float>, System.Numerics.IComparisonOperators<float,float,bool>, System.Numerics.IDecrementOperators<float>, System.Numerics.IDivisionOperators<float,float,float>, System.Numerics.IEqualityOperators<float,float,bool>, System.Numerics.IExponentialFunctions<float>, System.Numerics.IFloatingPoint<float>, System.Numerics.IFloatingPointConstants<float>, System.Numerics.IFloatingPointIeee754<float>, System.Numerics.IHyperbolicFunctions<float>, System.Numerics.IIncrementOperators<float>, System.Numerics.ILogarithmicFunctions<float>, System.Numerics.IMinMaxValue<float>, System.Numerics.IModulusOperators<float,float,float>, System.Numerics.IMultiplicativeIdentity<float,float>, System.Numerics.IMultiplyOperators<float,float,float>, System.Numerics.INumber<float>, System.Numerics.INumberBase<float>, System.Numerics.IPowerFunctions<float>, System.Numerics.IRootFunctions<float>, System.Numerics.ISignedNumber<float>, System.Numerics.ISubtractionOperators<float,float,float>, System.Numerics.ITrigonometricFunctions<float>, System.Numerics.IUnaryNegationOperators<float,float>, System.Numerics.IUnaryPlusOperators<float,float>
[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
type single = struct
interface IConvertible
interface IFormattable
interface IParsable<single>
interface ISpanFormattable
interface ISpanParsable<single>
interface IAdditionOperators<single, single, single>
interface IAdditiveIdentity<single, single>
interface IBinaryFloatingPointIeee754<single>
interface IBinaryNumber<single>
interface IBitwiseOperators<single, single, single>
interface IComparisonOperators<single, single, bool>
interface IEqualityOperators<single, single, bool>
interface IDecrementOperators<single>
interface IDivisionOperators<single, single, single>
interface IIncrementOperators<single>
interface IModulusOperators<single, single, single>
interface IMultiplicativeIdentity<single, single>
interface IMultiplyOperators<single, single, single>
interface INumber<single>
interface INumberBase<single>
interface ISubtractionOperators<single, single, single>
interface IUnaryNegationOperators<single, single>
interface IUnaryPlusOperators<single, single>
interface IExponentialFunctions<single>
interface IFloatingPointConstants<single>
interface IFloatingPoint<single>
interface ISignedNumber<single>
interface IFloatingPointIeee754<single>
interface IHyperbolicFunctions<single>
interface ILogarithmicFunctions<single>
interface IPowerFunctions<single>
interface IRootFunctions<single>
interface ITrigonometricFunctions<single>
interface IMinMaxValue<single>
[<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 IAdditionOperators(Of Single, Single, Single), IAdditiveIdentity(Of Single, Single), IBinaryFloatingPointIeee754(Of Single), IBinaryNumber(Of Single), IBitwiseOperators(Of Single, Single, Single), IComparable(Of Single), IComparisonOperators(Of Single, Single, Boolean), IConvertible, IDecrementOperators(Of Single), IDivisionOperators(Of Single, Single, Single), IEqualityOperators(Of Single, Single, Boolean), IEquatable(Of Single), IExponentialFunctions(Of Single), IFloatingPoint(Of Single), IFloatingPointConstants(Of Single), IFloatingPointIeee754(Of Single), IHyperbolicFunctions(Of Single), IIncrementOperators(Of Single), ILogarithmicFunctions(Of Single), IMinMaxValue(Of Single), IModulusOperators(Of Single, Single, Single), IMultiplicativeIdentity(Of Single, Single), IMultiplyOperators(Of Single, Single, Single), INumber(Of Single), INumberBase(Of Single), IParsable(Of Single), IPowerFunctions(Of Single), IRootFunctions(Of Single), ISignedNumber(Of Single), ISpanParsable(Of Single), ISubtractionOperators(Of Single, Single, Single), ITrigonometricFunctions(Of Single), IUnaryNegationOperators(Of Single, Single), IUnaryPlusOperators(Of Single, Single)
Public Structure Single
Implements IComparable, IConvertible, IFormattable
Public Structure Single
Implements IComparable, IComparable(Of Single), IEquatable(Of Single), IFormattable
- Ereditarietà
- Attributi
- Implementazioni
-
IComparable IComparable<Single> IConvertible IEquatable<Single> IFormattable ISpanFormattable IComparable<TSelf> IEquatable<TSelf> IParsable<Single> IParsable<TSelf> ISpanParsable<Single> ISpanParsable<TSelf> IAdditionOperators<Single,Single,Single> IAdditionOperators<TSelf,TSelf,TSelf> IAdditiveIdentity<Single,Single> IAdditiveIdentity<TSelf,TSelf> IBinaryFloatingPointIeee754<Single> IBinaryNumber<Single> IBinaryNumber<TSelf> IBitwiseOperators<Single,Single,Single> IBitwiseOperators<TSelf,TSelf,TSelf> IComparisonOperators<Single,Single,Boolean> IComparisonOperators<TSelf,TSelf,Boolean> IDecrementOperators<Single> IDecrementOperators<TSelf> IDivisionOperators<Single,Single,Single> IDivisionOperators<TSelf,TSelf,TSelf> IEqualityOperators<Single,Single,Boolean> IEqualityOperators<TSelf,TOther,TResult> IEqualityOperators<TSelf,TSelf,Boolean> IExponentialFunctions<Single> IExponentialFunctions<TSelf> IFloatingPoint<Single> IFloatingPoint<TSelf> IFloatingPointConstants<Single> IFloatingPointConstants<TSelf> IFloatingPointIeee754<Single> IFloatingPointIeee754<TSelf> IHyperbolicFunctions<Single> IHyperbolicFunctions<TSelf> IIncrementOperators<Single> IIncrementOperators<TSelf> ILogarithmicFunctions<Single> ILogarithmicFunctions<TSelf> IMinMaxValue<Single> IModulusOperators<Single,Single,Single> IModulusOperators<TSelf,TSelf,TSelf> IMultiplicativeIdentity<Single,Single> IMultiplicativeIdentity<TSelf,TSelf> IMultiplyOperators<Single,Single,Single> IMultiplyOperators<TSelf,TSelf,TSelf> INumber<Single> INumber<TSelf> INumberBase<Single> INumberBase<TSelf> IPowerFunctions<Single> IPowerFunctions<TSelf> IRootFunctions<Single> IRootFunctions<TSelf> ISignedNumber<Single> ISignedNumber<TSelf> ISubtractionOperators<Single,Single,Single> ISubtractionOperators<TSelf,TSelf,TSelf> ITrigonometricFunctions<Single> ITrigonometricFunctions<TSelf> IUnaryNegationOperators<Single,Single> IUnaryNegationOperators<TSelf,TSelf> IUnaryPlusOperators<Single,Single> IUnaryPlusOperators<TSelf,TSelf>
Commenti
Il Single tipo valore rappresenta un numero a precisione singola a 32 bit con valori compresi tra 3,402823e38 e 3,402823e38, nonché zero positivo o negativo, PositiveInfinity, NegativeInfinitye non un numero (NaN). È destinato a rappresentare valori estremamente grandi (ad esempio distanze tra pianeti o galassie) o estremamente piccole (come la massa molecolare di una sostanza in chilogrammi) e che spesso sono imprecise (come la distanza dalla terra a un altro sistema solare). Il Single tipo è conforme allo standard IEC 60559:1989 (IEEE 754) per l'aritmetica a virgola mobile binaria.
Questo articolo è costituito dalle sezioni seguenti:
System.Single fornisce metodi per confrontare le istanze di questo tipo, per convertire il valore di un'istanza nella relativa rappresentazione di stringa e per convertire la rappresentazione di stringa di un numero in un'istanza di questo tipo. Per informazioni su come i codici di specifica del formato controllano la rappresentazione di stringa dei tipi valore, vedere Formattazione di tipi, stringhe di formato numerico standard e stringhe di formato numerico personalizzato.
Rappresentazione a virgola mobile e precisione
Il Single tipo di dati archivia valori a virgola mobile e precisione singola in un formato binario a 32 bit, come illustrato nella tabella seguente:
Parte | BITS |
---|---|
Significando o mantissa | 0-22 |
Exponent | 23-30 |
Segno (0 = positivo, 1 = negativo) | 31 |
Proprio come le frazioni decimali non sono in grado di rappresentare con precisione alcuni valori frazionari (ad esempio 1/3 o Math.PI), le frazioni binarie non sono in grado di rappresentare alcuni valori frazionari. Ad esempio, 2/10, rappresentato esattamente da .2 come frazione decimale, è rappresentato da .0011111001001100 come frazione binaria, con il modello "1100" ripetuto all'infinito. In questo caso, il valore a virgola mobile fornisce una rappresentazione imprecisa del numero rappresentato. L'esecuzione di operazioni matematiche aggiuntive sul valore a virgola mobile originale spesso aumenta la mancanza di precisione. Ad esempio, se si confrontano i risultati della moltiplicazione di .3 per 10 e si aggiunge .3 a .3 nove volte, si noterà che l'aggiunta produce il risultato meno preciso, perché prevede otto operazioni più di moltiplicazione. Si noti che questa disparità è evidente solo se si visualizzano i due Single valori usando la stringa di formato numerico standard "R", che, se necessario, visualizza tutte e 9 le cifre di precisione supportate dal Single tipo.
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
let value = 0.2f
let result1 = value * 10f
let mutable result2 = 0f
for _ = 1 to 10 do
result2 <- result2 + value
printfn $".2 * 10: {result1:R}"
printfn $".2 Added 10 times: {result2:R}"
// 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
Poiché alcuni numeri non possono essere rappresentati esattamente come valori binari frazionari, i numeri a virgola mobile possono solo approssimare numeri reali.
Tutti i numeri a virgola mobile hanno un numero limitato di cifre significative, che determina anche in che modo un valore a virgola mobile approssima un numero reale. Un Single valore ha fino a 7 cifre decimali di precisione, anche se un massimo di 9 cifre viene mantenuto internamente. Ciò significa che alcune operazioni a virgola mobile potrebbero non avere la precisione per modificare un valore a virgola mobile. Nell'esempio seguente viene definito un valore a virgola mobile e precisione singola di grandi dimensioni e quindi viene aggiunto il prodotto di Single.Epsilon e un quadrillione. Tuttavia, il prodotto è troppo piccolo per modificare il valore a virgola mobile originale. La cifra meno significativa è millesimi, mentre la cifra più significativa del prodotto è 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
open System
let value = 123.456f
let additional = Single.Epsilon * 1e15f
printfn $"{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
La precisione limitata di un numero a virgola mobile ha diverse conseguenze:
Due numeri a virgola mobile apparentemente uguali per una particolare precisione potrebbero non risultare uguali, in quanto le relative cifre meno significative sono diverse. Nell'esempio seguente viene aggiunta una serie di numeri e il relativo totale viene confrontato con il totale previsto. Anche se i due valori sembrano essere uguali, una chiamata al
Equals
metodo indica che non sono.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).
let values = [| 10.01f; 2.88f; 2.88f; 2.88f; 9f |] let result = 27.65f let mutable total = 0f for value in values do total <- total + value if total.Equals result then printfn "The sum of the values equals the total." else printfn "The sum of the values ({total}) does not equal the 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).
Se si modificano gli elementi di formato nell'istruzione Console.WriteLine(String, Object, Object) da
{0}
e{1}
verso{0:R}
e{1:R}
per visualizzare tutte le cifre significative dei due valori, è chiaro che i due Single valori non sono uguali a causa di una perdita di precisione durante le operazioni di aggiunta. In questo caso, il problema può essere risolto chiamando il Math.Round(Double, Int32) metodo per arrotondare i Single valori alla precisione desiderata prima di eseguire il confronto.Un'operazione matematica o di confronto che usa un numero a virgola mobile potrebbe non restituire lo stesso risultato se viene usato un numero decimale, perché il numero a virgola mobile binaria potrebbe non corrispondere al numero decimale. Un esempio precedente ha illustrato questa operazione visualizzando il risultato della moltiplicazione di .3 per 10 e l'aggiunta di .3 a 3 volte.
Quando l'accuratezza nelle operazioni numeriche con valori frazionari è importante, usare il Decimal tipo anziché il Single tipo. Quando l'accuratezza nelle operazioni numeriche con valori integrali oltre l'intervallo di Int64 tipi o UInt64 è importante, usare il BigInteger tipo.
Un valore potrebbe non essere round trip se è coinvolto un numero a virgola mobile. Un valore viene detto round trip se un'operazione converte un numero a virgola mobile originale in un'altra forma, un'operazione inversa trasforma il modulo convertito in un numero a virgola mobile e il numero a virgola mobile finale è uguale al numero a virgola mobile originale. Il round trip potrebbe non riuscire perché una o più cifre significative vengono perse o modificate in una conversione. Nell'esempio seguente vengono convertiti tre Single valori in stringhe e salvati in un file. Come illustrato dall'output, anche se i valori sembrano essere identici, i valori ripristinati non sono uguali ai valori originali.
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
open System open System.IO let values = [| 3.2f / 1.11f; 1f / 3f; MathF.PI |] do use sw = new StreamWriter(@".\Singles.dat") for i = 0 to values.Length - 1 do sw.Write(string values[i]) if i <> values.Length - 1 then sw.Write "|" let restoredValues = use sr = new StreamReader(@".\Singles.dat") sr.ReadToEnd().Split '|' |> Array.map Single.Parse for i = 0 to values.Length - 1 do printfn $"""{values[i]} {if values[i].Equals restoredValues[i] then "=" else "<>"} {restoredValues[i]}""" // 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
In questo caso, i valori possono essere arrotondati correttamente usando la stringa di formato numerico standard "G9" per mantenere la precisione completa dei Single valori, come illustrato nell'esempio seguente.
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
open System open System.IO let values = [| 3.2f / 1.11f; 1f / 3f; MathF.PI |] do use sw = new StreamWriter(@".\Singles.dat") for i = 0 to values.Length - 1 do sw.Write $"""{values[i]:G9}{if i < values.Length - 1 then "|" else ""}""" let restoredValues = use sr = new StreamReader(@".\Singles.dat") sr.ReadToEnd().Split '|' |> Array.map Single.Parse for i = 0 to values.Length - 1 do printfn $"""{values[i]} {if values[i].Equals restoredValues[i] then "=" else "<>"} {restoredValues[i]}""" // 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 i valori hanno una precisione minore dei Double valori. Un Single valore convertito in un equivalente apparentemente non è uguale Double al Double valore a causa delle differenze di precisione. Nell'esempio seguente il risultato di operazioni di divisione identiche viene assegnato a un valore e a un DoubleSingle valore. Dopo che il Single valore viene eseguito il cast in un Doubleoggetto , un confronto dei due valori mostra che sono uguali.
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
open System let value1 = 1. / 3. let sValue2 = 1f /3f let value2 = double sValue2 printfn $"{value1:R} = {value2:R}: {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
Per evitare questo problema, usare il Double tipo di dati al posto del Single tipo di dati o usare il Round metodo in modo che entrambi i valori abbiano la stessa precisione.
Test per l'uguaglianza
Per essere considerato uguale, due Single valori devono rappresentare valori identici. Tuttavia, a causa delle differenze di precisione tra valori o a causa di una perdita di precisione per uno o entrambi i valori, i valori a virgola mobile che si prevede siano identici spesso risultano uguali a causa delle differenze nelle cifre meno significative. Di conseguenza, chiama al Equals metodo per determinare se due valori sono uguali o chiamate al CompareTo metodo per determinare la relazione tra due Single valori, spesso restituisce risultati imprevisti. Questo è evidente nell'esempio seguente, dove due valori apparentemente uguali Single diventano uguali, perché il primo valore ha 7 cifre di precisione, mentre il secondo valore ha 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
let value1 = 0.3333333f
let value2 = 1f / 3f
printfn $"{value1:R} = {value2:R}: {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
I valori calcolati che seguono percorsi di codice diversi e che vengono modificati in modi diversi spesso si rivelano non uguali. Nell'esempio seguente un Single valore è quadrato e quindi la radice quadrata viene calcolata per ripristinare il valore originale. Un secondo Single viene moltiplicato per 3,51 e quadrato prima della radice quadrata del risultato è diviso per 3,51 per ripristinare il valore originale. Anche se i due valori sembrano essere identici, una chiamata al Equals(Single) metodo indica che non sono uguali. Usando la stringa di formato standard "G9" per restituire una stringa di risultato che visualizza tutte le cifre significative di ogni Single valore mostra che il secondo valore è .0000000000001 minore del primo.
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
let value1 =
10.201438f ** 2f
|> sqrt
let value2 =
((value1 * 3.51f) ** 2f |> sqrt) / 3.51f
printfn $"{value1} = {value2}: {value1.Equals value2}\n"
printfn $"{value1:G9} = {value2:G9}"
// 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
Nei casi in cui è probabile che una perdita di precisione influisca sul risultato di un confronto, è possibile usare le tecniche seguenti anziché chiamare il Equals metodo o CompareTo :
Chiamare il Math.Round metodo per assicurarsi che entrambi i valori abbiano la stessa precisione. Nell'esempio seguente viene modificato un esempio precedente per usare questo approccio in modo che due valori frazionari siano equivalenti.
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
open System let value1 = 0.3333333f let value2 = 1f / 3f let precision = 7 let value1r = Math.Round(float value1, precision) |> float32 let value2r = Math.Round(float value2, precision) |> float32 printfn $"{value1:R} = {value2:R}: {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
Il problema della precisione si applica ancora all'arrotondamento dei valori a metà punto. Per altre informazioni, vedere il metodo Math.Round(Double, Int32, MidpointRounding).
Testare l'uguaglianza approssimativa anziché l'uguaglianza. Questa tecnica richiede che si definisci una quantità assoluta in base alla quale i due valori possono essere diversi ma comunque uguali o che definisci una quantità relativa in base alla quale il valore più piccolo può essere diverso dal valore più grande.
Avviso
Single.Epsilon a volte viene usato come misura assoluta della distanza tra due Single valori durante il test per l'uguaglianza. Tuttavia, Single.Epsilon misura il valore più piccolo possibile che può essere aggiunto a o sottratto da, un Single il cui valore è zero. Per la maggior parte dei valori positivi e negativi Single , il valore di Single.Epsilon è troppo piccolo da rilevare. Pertanto, ad eccezione dei valori zero, non è consigliabile usarlo nei test per l'uguaglianza.
Nell'esempio seguente viene usato l'approccio seguente per definire un
IsApproximatelyEqual
metodo che verifica la differenza relativa tra due valori. Contrasta anche il risultato delle chiamate alIsApproximatelyEqual
metodo e al Equals(Single) metodo.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
open System let isApproximatelyEqual value1 value2 epsilon = // If they are equal anyway, just return True. if value1.Equals value2 then true // Handle NaN, Infinity. elif Single.IsInfinity value1 || Single.IsNaN value1 then value1.Equals value2 elif Single.IsInfinity value2 || Single.IsNaN value2 then value1.Equals value2 else // Handle zero to avoid division by zero let divisor = max value1 value2 let divisor = if divisor.Equals 0 then min value1 value2 else divisor abs (value1 - value2) / divisor <= epsilon let one1 = 0.1f * 10f let mutable one2 = 0f for _ = 1 to 10 do one2 <- one2 + 0.1f printfn $"{one1:R} = {one2:R}: {one1.Equals one2}" printfn $"{one1:R} is approximately equal to {one2:R}: {isApproximatelyEqual one1 one2 0.000001f}" // 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
Valori e eccezioni a virgola mobile
Le operazioni con valori a virgola mobile non generano eccezioni, a differenza delle operazioni con tipi integrali, che generano eccezioni nei casi di operazioni illegali, ad esempio divisione per zero o overflow. In queste situazioni, invece, il risultato di un'operazione a virgola mobile è zero, infinito positivo, infinito negativo o non un numero (NaN):
Se il risultato di un'operazione a virgola mobile è troppo piccolo per il formato di destinazione, il risultato è zero. Ciò può verificarsi quando vengono moltiplicati due numeri a virgola mobile molto piccoli, come illustrato nell'esempio seguente.
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
let value1 = 1.163287e-36f let value2 = 9.164234e-25f let result = value1 * value2 printfn $"{value1} * {value2} = {result}" printfn $"{result} = 0: {result.Equals(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
Se la grandezza del risultato di un'operazione a virgola mobile supera l'intervallo del formato di destinazione, il risultato dell'operazione è PositiveInfinity o NegativeInfinity, come appropriato per il segno del risultato. Il risultato di un'operazione che esegue il overflow è e il risultato di un'operazione che esegue il overflow Single.MaxValueSingle.MinValue è PositiveInfinityNegativeInfinity, come illustrato nell'esempio seguente.
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
open System let value1 = 3.065e35f let value2 = 6.9375e32f let result = value1 * value2 printfn $"PositiveInfinity: {Single.IsPositiveInfinity result}" printfn $"NegativeInfinity: {Single.IsNegativeInfinity result}\n" let value3 = -value1 let result2 = value3 * value2 printfn $"PositiveInfinity: {Single.IsPositiveInfinity result}" printfn $"NegativeInfinity: {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 risulta anche da una divisione per zero con un dividendo positivo e NegativeInfinity risultati da una divisione per zero con un dividendo negativo.
Se un'operazione a virgola mobile non è valida, il risultato dell'operazione è NaN. Ad esempio, NaN i risultati delle operazioni seguenti:
Divisione per zero con un dividendo pari a zero. Si noti che altri casi di divisione per zero generano PositiveInfinity o NegativeInfinity.
Qualsiasi operazione a virgola mobile con input non valido. Ad esempio, il tentativo di trovare la radice quadrata di un valore negativo restituisce NaN.
Qualsiasi operazione con un argomento il cui valore è Single.NaN.
Conversioni di tipi e struttura singola
La Single struttura non definisce operatori di conversione espliciti o impliciti; invece, le conversioni vengono implementate dal compilatore.
Nella tabella seguente sono elencate le possibili conversioni di un valore degli altri tipi numerici primitivi in un Single valore, indica anche se la conversione si espande o restringe e se il risultato Single può avere una precisione minore del valore originale.
Conversione da | Estensione/restringezione | Possibile perdita di precisione |
---|---|---|
Byte | Widening | No |
Decimal | Widening Si noti che C# richiede un operatore cast. |
Sì. Decimal supporta 29 cifre decimali di precisione; Single supporta 9. |
Double | Restringimento; I valori non compresi nell'intervallo vengono convertiti in Double.NegativeInfinity o Double.PositiveInfinity. | Sì. Double supporta 17 cifre decimali di precisione; Single supporta 9. |
Int16 | Widening | No |
Int32 | Widening | Sì. Int32 supporta 10 cifre decimali di precisione; Single supporta 9. |
Int64 | Widening | Sì. Int64 supporta 19 cifre decimali di precisione; Single supporta 9. |
SByte | Widening | No |
UInt16 | Widening | No |
UInt32 | Widening | Sì. UInt32 supporta 10 cifre decimali di precisione; Single supporta 9. |
UInt64 | Widening | Sì. Int64 supporta 20 cifre decimali di precisione; Single supporta 9. |
Nell'esempio seguente viene convertito il valore minimo o massimo di altri tipi numerici primitivi in un Single valore.
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)
open System
let values: obj list =
[ 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 ]
for value in values do
let sngValue =
match value with
| :? byte as v -> float32 v
| :? decimal as v -> float32 v
| :? double as v -> float32 v
| :? int16 as v -> float32 v
| :? int as v -> float32 v
| :? int64 as v -> float32 v
| :? int8 as v -> float32 v
| :? uint16 as v -> float32 v
| :? uint as v -> float32 v
| :? uint64 as v -> float32 v
| _ -> raise (NotImplementedException "Unknown Type")
printfn $"{value} ({value.GetType().Name}) --> {sngValue:R} ({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)
Inoltre, i valori , e convertno rispettivamente in Single.NaN, Single.PositiveInfinitye , e Single.NegativeInfinity.Double.NegativeInfinityDouble.PositiveInfinityDouble.NaNDouble
Si noti che la conversione del valore di alcuni tipi numerici in un Single valore può comportare una perdita di precisione. Come illustrato nell'esempio, una perdita di precisione è possibile quando si convertono Decimal, Int64DoubleUInt32Int32e UInt64 i valori in Single valori.
La conversione di un Single valore in un Double oggetto è una conversione più ampia. La conversione può causare una perdita di precisione se il tipo non ha una rappresentazione precisa per il DoubleSingle valore.
La conversione di un Single valore in un valore di qualsiasi tipo di dati numerico primitivo diverso da una Double conversione è una conversione ristretta e richiede un operatore cast (in C#) o un metodo di conversione (in Visual Basic). I valori che non rientrano nell'intervallo del tipo di dati di destinazione, definiti dalle proprietà e MaxValue
del tipo di MinValue
destinazione, si comportano come illustrato nella tabella seguente.
Tipo di destinazione | Risultato |
---|---|
Qualsiasi tipo integrale | Eccezione OverflowException se la conversione si verifica in un contesto controllato. Se la conversione si verifica in un contesto deselezionato (impostazione predefinita in C#), l'operazione di conversione ha esito positivo, ma il valore supera i flussi. |
Decimal | Un'eccezione OverflowException , |
Inoltre, Single.NaN, Single.PositiveInfinitye Single.NegativeInfinity generano un'eccezione OverflowException per le conversioni in interi in un contesto controllato, ma questi valori superano l'overflow quando vengono convertiti in numeri interi in un contesto deselezionato. Per le conversioni in Decimal, generano sempre un oggetto OverflowException. Per le conversioni in Double, convertono Double.NaNrispettivamente in , Double.PositiveInfinitye Double.NegativeInfinity.
Si noti che una perdita di precisione può comportare la conversione di un Single valore in un altro tipo numerico. Nel caso della conversione di valori non integrali Single , come illustrato nell'output dell'esempio, il componente frazionaria viene perso quando il Single valore viene arrotondato (come in Visual Basic) o troncato (come in C# e F#). Per le conversioni in Decimal valori, il Single valore potrebbe non avere una rappresentazione precisa nel tipo di dati di destinazione.
Nell'esempio seguente viene convertito un numero di Single valori in diversi altri tipi numerici. Le conversioni si verificano in un contesto controllato in Visual Basic (impostazione predefinita), in C# (a causa della parola chiave selezionata ) e in F# (a causa dell'istruzione open Checked
). L'output dell'esempio mostra il risultato per le conversioni in un contesto selezionato. È possibile eseguire conversioni in un contesto non controllato in Visual Basic compilando con l'opzione del /removeintchecks+
compilatore, in C# impostando come commento l'istruzione checked
e in F# impostando come commento l'istruzione open 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)
open System
open Checked
let values =
[ Single.MinValue; -67890.1234f; -12345.6789f
12345.6789f; 67890.1234f; Single.MaxValue
Single.NaN; Single.PositiveInfinity
Single.NegativeInfinity ]
for value in values do
try
let lValue = int64 value
printfn $"{value} ({value.GetType().Name}) --> {lValue} (0x{lValue:X16}) ({lValue.GetType().Name})"
with :? OverflowException ->
printfn $"Unable to convert {value} to Int64."
try
let ulValue = uint64 value
printfn $"{value} ({value.GetType().Name}) --> {ulValue} (0x{ulValue:X16}) ({ulValue.GetType().Name})"
with :? OverflowException ->
printfn $"Unable to convert {value} to UInt64."
try
let dValue = decimal value
printfn $"{value} ({value.GetType().Name}) --> {dValue} ({dValue.GetType().Name})"
with :? OverflowException ->
printfn $"Unable to convert {value} to Decimal."
let dblValue = double value
printfn $"{value} ({value.GetType().Name}) --> {dblValue} ({dblValue.GetType().Name})\n"
// 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)
Per altre informazioni sulla conversione di tipi numerici, vedere Conversione dei tipi in .NET Framework e tabelle di conversione dei tipi.
Funzionalità a virgola mobile
La Single struttura e i tipi correlati forniscono metodi per eseguire le categorie di operazioni seguenti:
Confronto dei valori. È possibile chiamare il Equals metodo per determinare se due Single valori sono uguali o il CompareTo metodo per determinare la relazione tra due valori.
La Single struttura supporta anche un set completo di operatori di confronto. Ad esempio, è possibile verificare l'uguaglianza o la disuguaglianza oppure determinare se un valore è maggiore o uguale a un altro valore. Se uno degli operandi è un Double, il Single valore viene convertito in un Double oggetto prima di eseguire il confronto. Se uno degli operandi è un tipo integrale, viene convertito in un Single oggetto prima di eseguire il confronto. Sebbene queste conversioni vengano ampliate, possono comportare una perdita di precisione.
Avviso
A causa delle differenze di precisione, due Single valori che si prevede siano uguali possono risultare diversi, che influiscono sul risultato del confronto. Per altre informazioni sul confronto di due Single valori, vedere la sezione Test per l'uguaglianza.
È anche possibile chiamare i IsNaNmetodi , IsInfinity, IsPositiveInfinitye IsNegativeInfinity per testare questi valori speciali.
Operazioni matematiche. Le operazioni aritmetiche comuni, ad esempio addizione, sottrazione, moltiplicazione e divisione, vengono implementate dai compilatori del linguaggio e dalle istruzioni CIL (Common Intermediate Language) anziché dai Single metodi. Se l'altro operando in un'operazione matematica è , Doubleviene Single convertito in un Double oggetto prima di eseguire l'operazione e il risultato dell'operazione è anche un Double valore . Se l'altro operando è un tipo integrale, viene convertito in un Single oggetto prima di eseguire l'operazione e il risultato dell'operazione è anche un Single valore.
È possibile eseguire altre operazioni matematiche chiamando
static
(Shared
in Visual Basic) metodi nella System.Math classe . Questi includono metodi aggiuntivi comunemente usati per l'aritmetica (ad esempio , e ), la geometria (ad esempio e Math.Sin) e il calcolo (ad esempio Math.LogMath.Cos ).Math.SqrtMath.SignMath.Abs In tutti i casi, il Single valore viene convertito in .DoubleÈ anche possibile modificare i singoli bit in un Single valore. Il BitConverter.GetBytes(Single) metodo restituisce il modello di bit in una matrice di byte. Passando tale matrice di byte al BitConverter.ToInt32 metodo , è anche possibile mantenere il Single modello di bit del valore in un numero intero a 32 bit.
Arrotondamento. L'arrotondamento viene spesso usato come tecnica per ridurre l'impatto delle differenze tra i valori causati da problemi di rappresentazione a virgola mobile e precisione. È possibile arrotondamento di un Single valore chiamando il Math.Round metodo . Si noti tuttavia che il Single valore viene convertito in un Double oggetto prima della chiamata al metodo e la conversione può comportare una perdita di precisione.
Formattazione. È possibile convertire un Single valore nella relativa rappresentazione di stringa chiamando il ToString metodo o usando la funzionalità di formattazione composita . Per informazioni su come le stringhe di formato controllano la rappresentazione di stringa dei valori a virgola mobile, vedere gli argomenti Stringhe di formato numerico standard e Stringhe di formato numerico personalizzato .
Analisi delle stringhe. È possibile convertire la rappresentazione di stringa di un valore a virgola mobile in un Single valore chiamando il Parse metodo o TryParse . Se l'operazione di analisi ha esito negativo, il Parse metodo genera un'eccezione, mentre il TryParse metodo restituisce
false
.Conversione dei tipi. La Single struttura fornisce un'implementazione esplicita dell'interfaccia che supporta la IConvertible conversione tra due tipi di dati .NET Framework standard. I compilatori del linguaggio supportano anche la conversione implicita di valori per tutti gli altri tipi numerici standard, ad eccezione della conversione di Double in Single valori. La conversione di un valore di qualsiasi tipo numerico standard diverso da a DoubleSingle è una conversione più ampia e non richiede l'uso di un operatore di cast o di un metodo di conversione.
Tuttavia, la conversione di valori integer a 32 bit e a 64 bit può comportare una perdita di precisione. Nella tabella seguente sono elencate le differenze di precisione per i tipi a 32 bit, a 64 bit e Double :
Tipo Precisione massima (in cifre decimali) Precisione interna (in cifre decimali) Double 15 17 Int32 e UInt32 10 10 Int64 e UInt64 19 19 Single 7 9 Il problema della precisione influisce più frequentemente sui Single valori convertiti in Double valori. Nell'esempio seguente due valori generati da operazioni di divisione identiche sono diversi, perché uno dei valori è un valore a virgola mobile a precisione singola convertito in .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
let value1 = 1. / 3. let sValue2 = 1f / 3f let value2 = double sValue2 printfn $"{value1:R} = {value2:R}: {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
Campi
E |
Rappresenta la base logaritmica naturale, specificata dalla costante, e. |
Epsilon |
Rappresenta il valore Single positivo più piccolo maggiore di zero. Questo campo è costante. |
MaxValue |
Rappresenta il valore massimo possibile di Single. Questo campo è costante. |
MinValue |
Rappresenta il valore più piccolo possibile di Single. Questo campo è costante. |
NaN |
Rappresenta un valore non numerico ( |
NegativeInfinity |
Rappresenta l'infinito negativo. Questo campo è costante. |
NegativeZero |
Rappresenta il numero negativo zero (-0). |
Pi |
Rappresenta il rapporto tra la circonferenza del cerchio e il relativo diametro, specificato dalla costante π. |
PositiveInfinity |
Rappresenta l'infinito positivo. Questo campo è costante. |
Tau |
Rappresenta il numero di radianti in un angolo giro, specificati dalla costante τ. |
Metodi
Abs(Single) |
Calcola l'assoluto di un valore. |
Acos(Single) |
Calcola l'arco coseno di un valore. |
Acosh(Single) |
Calcola l'arco-coseno iperbolico di un valore. |
AcosPi(Single) |
Calcola l'arco coseno di un valore e divide il risultato per |
Asin(Single) |
Calcola il seno arco di un valore. |
Asinh(Single) |
Calcola il seno iperbolico di un valore. |
AsinPi(Single) |
Calcola il seno arco di un valore e divide il risultato per |
Atan(Single) |
Calcola l'arco tangente di un valore. |
Atan2(Single, Single) |
Calcola l'arco tangente del quoziente di due valori. |
Atan2Pi(Single, Single) |
Calcola l'arco-tangente per il quoziente di due valori e divide il risultato per |
Atanh(Single) |
Calcola la tangente iperbolica di un valore. |
AtanPi(Single) |
Calcola l'arco tangente di un valore e divide il risultato per pi. |
BitDecrement(Single) |
Decrementa un valore con il valore più piccolo che confronta meno di un valore specificato. |
BitIncrement(Single) |
Incrementa un valore al valore più piccolo che confronta maggiore di un valore specificato. |
Cbrt(Single) |
Calcola la radice del cubo di un valore. |
Ceiling(Single) |
Calcola il limite massimo di un valore. |
Clamp(Single, Single, Single) |
Blocca un valore a un valore minimo e massimo inclusivo. |
CompareTo(Object) |
Confronta questa istanza con un oggetto specificato e restituisce un intero che indica se il valore di questa istanza è minore, uguale o maggiore rispetto al valore dell'oggetto specificato. |
CompareTo(Single) |
Confronta questa istanza con un numero a virgola mobile a precisione singola specificato e restituisce un intero che indica se il valore di questa istanza è minore, uguale o maggiore del valore del numero a virgola mobile a precisione singola specificato. |
CopySign(Single, Single) |
Copia il segno di un valore nel segno di un altro valore. |
Cos(Single) |
Calcola il coseno di un valore. |
Cosh(Single) |
Calcola il coseno iperbolico di un valore. |
CosPi(Single) |
Calcola il coseno di un valore multiplo da |
CreateChecked<TOther>(TOther) |
Crea un'istanza del tipo corrente da un valore, che genera un'eccezione di overflow per tutti i valori che non rientrano nell'intervallo rappresentabile del tipo corrente. |
CreateSaturating<TOther>(TOther) |
Crea un'istanza del tipo corrente da un valore, saturando tutti i valori che non rientrano nell'intervallo rappresentabile del tipo corrente. |
CreateTruncating<TOther>(TOther) |
Crea un'istanza del tipo corrente da un valore, troncando tutti i valori che non rientrano nell'intervallo rappresentabile del tipo corrente. |
Equals(Object) |
Restituisce un valore che indica se questa istanza è uguale a un oggetto specificato. |
Equals(Single) |
Restituisce un valore che indica se l'istanza e un oggetto Single specificato rappresentano lo stesso valore. |
Exp(Single) |
|
Exp10(Single) |
|
Exp10M1(Single) |
|
Exp2(Single) |
|
Exp2M1(Single) |
|
ExpM1(Single) |
|
Floor(Single) |
Calcola il piano di un valore. |
FusedMultiplyAdd(Single, Single, Single) |
Calcola l'aggiunta moltiplicata di tre valori. |
GetHashCode() |
Restituisce il codice hash per l'istanza. |
GetTypeCode() | |
Hypot(Single, Single) |
Calcola l'ipotenusa dato due valori che rappresentano le lunghezze dei lati più corti in un triangolo ad angolo destro. |
Ieee754Remainder(Single, Single) |
Calcola il resto di due valori come specificato da IEEE 754. |
ILogB(Single) |
Calcola il logaritmo intero di un valore. |
IsEvenInteger(Single) |
Determina se un valore rappresenta un numero integrale pari. |
IsFinite(Single) |
Determina se il valore specificato è finito (zero, subnormale o normale). |
IsInfinity(Single) |
Restituisce un valore che indica se il numero specificato restituisce l'infinito negativo o positivo. |
IsInteger(Single) |
Determina se un valore rappresenta un valore integrale. |
IsNaN(Single) |
Restituisce un valore che indica se il valore specificato non è un numero (NaN). |
IsNegative(Single) |
Determina se il valore specificato è negativo. |
IsNegativeInfinity(Single) |
Restituisce un valore che indica se il numero specificato restituisce l'infinito negativo. |
IsNormal(Single) |
Determina se il valore specificato è normale. |
IsOddInteger(Single) |
Determina se un valore rappresenta un numero integrale dispari. |
IsPositive(Single) |
Determina se un valore è positivo. |
IsPositiveInfinity(Single) |
Restituisce un valore che indica se il numero specificato restituisce l'infinito positivo. |
IsPow2(Single) |
Determina se un valore è una potenza di due. |
IsRealNumber(Single) |
Determina se un valore rappresenta un numero reale. |
IsSubnormal(Single) |
Determina se il valore specificato è subnormale. |
Log(Single) |
Calcola il logaritmo naturale |
Log(Single, Single) |
Calcola il logaritmo di un valore nella base specificata. |
Log10(Single) |
Calcola il logaritmo di base 10 di un valore. |
Log10P1(Single) |
Calcola il logaritmo di base 10 di un valore più uno. |
Log2(Single) |
Calcola il log2 di un valore. |
Log2P1(Single) |
Calcola il logaritmo di base 2 di un valore più uno. |
LogP1(Single) |
Calcola il logaritmo naturale ( |
Max(Single, Single) |
Confronta due valori con il calcolo maggiore. |
MaxMagnitude(Single, Single) |
Confronta due valori con il calcolo maggiore. |
MaxMagnitudeNumber(Single, Single) |
Confronta due valori con il calcolo che ha la grandezza maggiore e restituisce l'altro valore se un input è |
MaxNumber(Single, Single) |
Confronta due valori con il calcolo che è maggiore e restituisce l'altro valore se un input è |
Min(Single, Single) |
Confronta due valori con il calcolo minore. |
MinMagnitude(Single, Single) |
Confronta due valori con il calcolo minore. |
MinMagnitudeNumber(Single, Single) |
Confronta due valori con il calcolo con la grandezza minore e restituendo l'altro valore se un input è |
MinNumber(Single, Single) |
Confronta due valori con il calcolo minore e restituendo l'altro valore se un input è |
Parse(ReadOnlySpan<Char>, IFormatProvider) |
Analizza un intervallo di caratteri in un valore. |
Parse(ReadOnlySpan<Char>, NumberStyles, IFormatProvider) |
Converte un intervallo di caratteri che contiene la rappresentazione stringa di un numero in uno stile specificato e in un formato specifico delle impostazioni cultura nel numero a virgola mobile a precisione singola equivalente. |
Parse(String) |
Converte la rappresentazione di stringa di un numero nel numero a virgola mobile a precisione singola equivalente. |
Parse(String, IFormatProvider) |
Converte la rappresentazione di stringa di un numero in un determinato formato specifico delle impostazioni cultura nel numero a virgola mobile a precisione singola equivalente. |
Parse(String, NumberStyles) |
Converte la rappresentazione di stringa di un numero in uno stile specificato nel rispettivo numero a virgola mobile a precisione singola equivalente. |
Parse(String, NumberStyles, IFormatProvider) |
Converte la rappresentazione di stringa di un numero in uno stile specificato e in un formato specifico delle impostazioni cultura nel numero a virgola mobile a precisione singola equivalente. |
Pow(Single, Single) |
Calcola un valore elevato a una determinata potenza. |
ReciprocalEstimate(Single) |
Calcola una stima del reciproco di un valore. |
ReciprocalSqrtEstimate(Single) |
Calcola una stima della radice quadrata reciproca di un valore. |
RootN(Single, Int32) |
Calcola la radice n-th di un valore. |
Round(Single) |
Arrotonda un valore all'intero più vicino usando la modalità di arrotondamento predefinita (ToEven). |
Round(Single, Int32) |
Arrotonda un valore a un numero specificato di cifre frazionarie usando la modalità di arrotondamento predefinita (ToEven). |
Round(Single, Int32, MidpointRounding) |
Arrotonda un valore a un numero specificato di cifre frazionarie usando la modalità di arrotondamento predefinita (ToEven). |
Round(Single, MidpointRounding) |
Arrotonda un valore all'intero più vicino utilizzando la modalità di arrotondamento specificata. |
ScaleB(Single, Int32) |
Calcola il prodotto di un valore e il relativo radix di base elevato alla potenza specificata. |
Sign(Single) |
Calcola il segno di un valore. |
Sin(Single) |
Calcola il seno di un valore. |
SinCos(Single) |
Calcola il seno e il coseno di un valore. |
SinCosPi(Single) |
Calcola il seno e il coseno di un valore. |
Sinh(Single) |
Calcola il seno iperbolico di un valore. |
SinPi(Single) |
Calcola il seno di un valore moltiplicato per |
Sqrt(Single) |
Calcola la radice quadrata di un valore. |
Tan(Single) |
Calcola la tangente di un valore. |
Tanh(Single) |
Calcola la tangente iperbolica di un valore. |
TanPi(Single) |
Calcola la tangente di un valore multiplo da |
ToString() |
Converte il valore numerico dell'istanza nella rappresentazione di stringa equivalente. |
ToString(IFormatProvider) |
Converte il valore numerico di questa istanza nella rappresentazione di stringa equivalente usando le informazioni di formato specifiche delle impostazioni cultura. |
ToString(String) |
Converte il valore numerico di questa istanza nell'equivalente rappresentazione di stringa usando il formato specificato. |
ToString(String, IFormatProvider) |
Converte il valore numerico dell'istanza nella rappresentazione di stringa equivalente usando il formato specificato e le informazioni di formattazione specifiche delle impostazioni cultura. |
Truncate(Single) |
Tronca un valore. |
TryFormat(Span<Char>, Int32, ReadOnlySpan<Char>, IFormatProvider) |
Prova a formattare il valore dell'istanza del numero float corrente nell'intervallo di caratteri specificato. |
TryParse(ReadOnlySpan<Char>, IFormatProvider, Single) |
Tenta di analizzare un intervallo di caratteri in un valore. |
TryParse(ReadOnlySpan<Char>, NumberStyles, IFormatProvider, Single) |
Converte la rappresentazione intervallo di un numero in uno stile specificato e in un formato specifico delle impostazioni cultura nel numero a virgola mobile a precisione singola equivalente. Un valore restituito indica se la conversione è riuscita o meno. |
TryParse(ReadOnlySpan<Char>, Single) |
Converte la rappresentazione stringa di un numero in un intervallo di caratteri nel numero a virgola mobile a precisione singola equivalente. Un valore restituito indica se la conversione è riuscita o meno. |
TryParse(String, IFormatProvider, Single) |
Tenta di analizzare una stringa in un valore. |
TryParse(String, NumberStyles, IFormatProvider, Single) |
Converte la rappresentazione di stringa di un numero in uno stile specificato e in un formato specifico delle impostazioni cultura nel numero a virgola mobile a precisione singola equivalente. Un valore restituito indica se la conversione è riuscita o meno. |
TryParse(String, Single) |
Converte la rappresentazione di stringa di un numero nel numero a virgola mobile a precisione singola equivalente. Un valore restituito indica se la conversione è riuscita o meno. |
Operatori
Equality(Single, Single) |
Restituisce un valore che indica se due valori Single specificati sono uguali. |
GreaterThan(Single, Single) |
Restituisce un valore che indica se un valore Singlespecificato è maggiore di un altro valore Single specificato. |
GreaterThanOrEqual(Single, Single) |
Restituisce un valore che indica se un valore Single specificato è maggiore o uguale a un altro valore Single specificato. |
Inequality(Single, Single) |
Restituisce un valore che indica se due valori Single specificati non sono uguali. |
LessThan(Single, Single) |
Restituisce un valore che indica se il valore Single specificato è minore o uguale a un altro valore Single specificato. |
LessThanOrEqual(Single, Single) |
Restituisce un valore che indica se un valore Single specificato è minore o uguale a un altro valore Single specificato. |
Implementazioni dell'interfaccia esplicita
IComparable.CompareTo(Object) |
Confronta l'istanza corrente con un altro oggetto dello stesso tipo e restituisce un intero che indica se l'istanza corrente precede, segue o si trova nella stessa posizione dell'altro oggetto all'interno dell'ordinamento. |
IConvertible.GetTypeCode() |
Restituisce l'oggetto TypeCode per questa istanza. |
IConvertible.ToBoolean(IFormatProvider) |
Per una descrizione di questo membro, vedere ToBoolean(IFormatProvider). |
IConvertible.ToByte(IFormatProvider) |
Per una descrizione di questo membro, vedere ToByte(IFormatProvider). |
IConvertible.ToChar(IFormatProvider) |
Questa conversione non è supportata. Il tentativo di usare questo metodo genera un'eccezione InvalidCastException. |
IConvertible.ToDateTime(IFormatProvider) |
Questa conversione non è supportata. Il tentativo di usare questo metodo genera un'eccezione InvalidCastException. |
IConvertible.ToDecimal(IFormatProvider) |
Per una descrizione di questo membro, vedere ToDecimal(IFormatProvider). |
IConvertible.ToDouble(IFormatProvider) |
Per una descrizione di questo membro, vedere ToDouble(IFormatProvider). |
IConvertible.ToInt16(IFormatProvider) |
Per una descrizione di questo membro, vedere ToInt16(IFormatProvider). |
IConvertible.ToInt32(IFormatProvider) |
Per una descrizione di questo membro, vedere ToInt32(IFormatProvider). |
IConvertible.ToInt64(IFormatProvider) |
Per una descrizione di questo membro, vedere ToInt64(IFormatProvider). |
IConvertible.ToSByte(IFormatProvider) |
Per una descrizione di questo membro, vedere ToSByte(IFormatProvider). |
IConvertible.ToSingle(IFormatProvider) |
Per una descrizione di questo membro, vedere ToSingle(IFormatProvider). |
IConvertible.ToType(Type, IFormatProvider) |
Per una descrizione di questo membro, vedere ToType(Type, IFormatProvider). |
IConvertible.ToUInt16(IFormatProvider) |
Per una descrizione di questo membro, vedere ToUInt16(IFormatProvider). |
IConvertible.ToUInt32(IFormatProvider) |
Per una descrizione di questo membro, vedere ToUInt32(IFormatProvider). |
IConvertible.ToUInt64(IFormatProvider) |
Per una descrizione di questo membro, vedere ToUInt64(IFormatProvider). |
IFloatingPoint<Single>.GetExponentByteCount() |
Ottiene il numero di byte che verranno scritti come parte di TryWriteExponentLittleEndian(Span<Byte>, Int32). |
IFloatingPoint<Single>.GetExponentShortestBitLength() |
Ottiene la lunghezza, in bit, della rappresentazione di complemento più breve di due dell'esponente corrente. |
IFloatingPoint<Single>.GetSignificandBitLength() |
Ottiene la lunghezza, espressa in bit, del significando corrente. |
IFloatingPoint<Single>.GetSignificandByteCount() |
Ottiene il numero di byte che verranno scritti come parte di TryWriteSignificandLittleEndian(Span<Byte>, Int32). |
IFloatingPoint<Single>.TryWriteExponentBigEndian(Span<Byte>, Int32) |
Tenta di scrivere l'esponente corrente, in formato big-endian, in un determinato intervallo. |
IFloatingPoint<Single>.TryWriteExponentLittleEndian(Span<Byte>, Int32) |
Tenta di scrivere l'esponente corrente, in formato little-endian, in un determinato intervallo. |
IFloatingPoint<Single>.TryWriteSignificandBigEndian(Span<Byte>, Int32) |
Tenta di scrivere il significando corrente, in formato big-endian, in un determinato intervallo. |
IFloatingPoint<Single>.TryWriteSignificandLittleEndian(Span<Byte>, Int32) |
Tenta di scrivere il significando corrente, in formato little-endian, in un determinato intervallo. |
Si applica a
Thread safety
Tutti i membri di questo tipo sono thread-safe. I membri che sembrano modificare lo stato dell'istanza restituiscono effettivamente una nuova istanza inizializzata con il nuovo valore. Come per qualsiasi altro tipo, la lettura e la scrittura in una variabile condivisa che contiene un'istanza di questo tipo devono essere protette da un blocco per garantire la thread safety.