Domanda

Qualcuno di voi può spiegare perché questo succede?

static void Main()
{
    const float xScaleStart = 0.5f;
    const float xScaleStop = 4.0f;
    const float xScaleInterval = 0.1f;
    const float xScaleAmplitude = xScaleStop - xScaleStart;

    const float xScaleSizeC = xScaleAmplitude / xScaleInterval;

    float xScaleSize = xScaleAmplitude / xScaleInterval;

    Console.WriteLine(">const float {0}, (int){1}", xScaleSizeC, (int)xScaleSizeC);

    Console.WriteLine(">      float {0}, (int){1}", xScaleSize, (int)xScaleSize);

    Console.ReadLine();
}
.

Uscita:

>const float 35, (int)34
>      float 35, (int)35
.

So che la rappresentazione binaria di 0,1 è in realtà 0,09999990463256835937, anche se perché questo accade usando "Const Float" e non con "galleggiante"?È considerato un bug del compilatore?

Per il record, il codice compila in:

private static void Main(string[] args)
{
    float xScaleSize = 35f;
    Console.WriteLine(">const float {0}, (int){1}", 35f, 34);
    Console.WriteLine(">      float {0}, (int){1}", xScaleSize, (int)xScaleSize);
    Console.ReadLine();
}
.

È stato utile?

Soluzione

Il "perché" di ciò, fondamentalmente devia il fatto che frequentemente, quando si lavora con i dati float, è possibile utilizzare una rappresentazione interna che ha più precisione di quanto sia specificato per float o double. Questo è esplicitamente soddisfatto nella specifica del sistema di esecuzione virtuale (VES) (Sezione 12 di partition i ):

.

I numeri del punto flottanti sono rappresentati utilizzando un punto flottante interno genere. In ciascuna tali istanza, il tipo nominale della variabile o dell'espressione è float32 o float64, ma il suo Il valore può essere rappresentato internamente con un intervallo aggiuntivo e / o precisione

E poi più tardi abbiamo:

.

L'uso di una rappresentazione interna più larga di float32 o float64 può causare differenze in Risultati computazionali Quando uno sviluppatore fa modifiche apparentemente non correlate al loro codice, il risultato di che può essere che un valore viene versato dalla rappresentazione interna (ad esempio, in un registro) in una posizione sul Stack.

Ora, secondo il C # Specifiche linguistiche :

.

La valutazione del tempo di compilazione delle espressioni costanti utilizza le stesse regole della valutazione del tempo di esecuzione delle espressioni non costante, tranne che in cui la valutazione di runtime avrebbe lanciato un'eccezione, la valutazione della compilazione è un errore di compilazione a si verificano.

Ma mentre osserviamo sopra, le regole consentono effettivamente l'uso di più precisione a volte, e quando questa precisione avanzata è utilizzata non è in realtà sotto il nostro controllo diretto.


.

E ovviamente, in diverse circostanze, i risultati potrebbero essere stati precisamente l'opposto di ciò che hai osservato - il compilatore potrebbe essere rilasciato alla precisione più bassa e il runtime potrebbe aver mantenuto invece una precisione maggiore.

Altri suggerimenti

Non posso dire che questa è una domanda duplicata da qui -> Eric PostPischil Comment

ha spiegato qualcosa di simile riguardo all'int est int's.

L'idea principale è che la divisione di due costanti calcolata dal compilatore prima di generare il codice e non in runtime, ma in questo caso specifico ogni volta che il compilatore esegue questo esegue il calcolo in Doppio Formato.Pertanto, Xscaleszec è fondamentalmente uguale a 34.9999 ... quindi quando viene lanciato in fase di esecuzione per int, diventa 34.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top