Ci sono numeri che non sono rappresentabili nella base 10 ma possono essere rappresentati nella base 2?


42

C#ha il decimaltipo utilizzato per i numeri che richiedono una rappresentazione esatta nella base 10. Ad esempio, 0.1non può essere rappresentato nella base 2 (ad es. floate double) e sarà sempre un'approssimazione se memorizzato in variabili di questi tipi.

Mi chiedevo se fosse possibile anche il fatto inverso. Ci sono numeri che non sono rappresentabili nella base 10 ma possono essere rappresentati nella base 2 (nel qual caso vorrei usare un floatinvece di un decimalper gestirli)?


14
+1 alla domanda, ma il tag c # è davvero applicabile qui? Anche altre lingue hanno il tipo decimale.
Patrick M,

1
@Max: come esercizio, ti suggerisco di immaginare di convertire manualmente un numero base 2 in base 10. Ad esempio, per calcolare il valore di 0.11_b2, scriverlo come 0.5 + 0.5 * 0.5. Esiste un passaggio che potrebbe non riuscire o comportare un numero decimale ripetuto? Personalmente, trovo che questo esercizio faccia un ottimo lavoro nell'intuizione dei numeri di base 2. Suppongo che si potrebbe fare un ulteriore passo avanti e trasformare questo esercizio in una prova di costruzione.
Brian,

Ah, ma ti sbagli. 1/1010
Xavier J

3
@Ramhound Dati i limiti di memoria, il binario può rappresentare 0.0999999....998..esattamente, ma non il numero intero 0.1- approssimazioni come l'arrotondamento al hundreth più vicino con 0.100sono una preoccupazione di implementazione che implica non mostrare tutte le cifre e arrotondare invece.
Izkata,

1
Bene, è possibile escogitare un meccanismo di codifica FP che consenta di rappresentare esattamente "0.1". Una tale codifica si sposta semplicemente attorno agli insiemi di intervalli di numeri FP che possono e non possono essere rappresentati.
Martin James,

Risposte:


104

Ecco la chiave del tuo dilemma: 10è il prodotto di 2e 5. È possibile rappresentare qualsiasi numero esattamente in base 10 decimali che è k * 1/2 n * 1/5 m , dove k, ne msono interi.

In alternativa, se il numero nin 1 / n contiene un fattore che non fa parte dei fattori della base, il numero non potrà essere rappresentato esattamente in un numero fisso di cifre nel binario / decimale / qualunque espansione di tale numero - avrà una parte ripetuta. Ad esempio 1/15 = 0,0666666666 .... perché 3 (15 = 3 * 5) non è un fattore 10.

Pertanto, qualsiasi cosa in grado di essere rappresentata esattamente nella base 2 (k * 1/2 n ) può essere rappresentata esattamente nella base 10.

Oltre a ciò, c'è il problema di quante cifre / bit stai usando per rappresentare il numero. Ci sono alcuni numeri che possono essere rappresentati esattamente in qualche base, ma ci vuole più di un certo numero di cifre / bit per fare.


In binario, il numero 1/10 che è convenientemente in decimale 0,1 non può essere rappresentato come un numero che può essere rappresentato in un numero fisso di bit in binario. Invece, il numero è 0,00011001100110011 ... 2 (con la parte 0011 che si ripete per sempre).

Consente di guardare il numero 1 2 /1010 2 un po 'più da vicino.

          ____                  
       0,00011                  
     + ---------                 
1010 | 1.00000                  
       0                        
       -                       
       1 0                      
         0                      
       ----                     
       1 00 --------- +          
          0 |          
       ----- |          
       1 000 |          
           0 |          
       ------ | ripetendo
       1 0000 | bloccare    
         1010 |          
       ------ |          
          1100 |          
          1010 |          
          ---- |          
            100 ---- +          

Questo è esattamente lo stesso tipo di cose che ottieni quando provi a fare la divisione lunga per 1/3.

1/10, quando il factoring è 1 / (2 1 * 5 1 ). Per la base 10 (o qualsiasi multiplo di 10), questo numero termina ed è noto come un numero normale . Un'espansione decimale che si ripete è nota come decimale ricorrente e quei numeri che vanno avanti all'infinito senza ripetersi sono numeri irrazionali.

La matematica dietro questo approfondisce il piccolo teorema di Fermat ... e una volta che si inizia a dire Fermat o teorema, diventa una domanda Math.SE .

Ci sono numeri che non sono rappresentabili nella base 10 ma possono essere rappresentati nella base 2?

La risposta è no'.

Quindi, a questo punto dovremmo essere tutti chiari sul fatto che ogni espansione binaria a lunghezza fissa di un numero razionale può essere rappresentata come espansione decimale a lunghezza fissa.


Vediamo più da vicino il decimale in C # che ci porta al punto decimale in .NET e dato l'autore, accetterò che sia così.

Il tipo decimale ha gli stessi componenti di qualsiasi altro numero in virgola mobile: una mantissa, un esponente e un segno. Come al solito, il segno è solo un singolo bit, ma ci sono 96 bit di mantissa e 5 bit di esponente. Tuttavia, non tutte le combinazioni di esponenti sono valide. Funzionano solo i valori 0-28 e sono effettivamente tutti negativi: il valore numerico è . Ciò significa che i valori massimo e minimo del tipo sono +/- (2 96 -1) e il numero minore diverso da zero in termini di magnitudine assoluta è 10 -28 .sign * mantissa / 10exponent

Sottolineerò subito che a causa di questa implementazione ci sono numeri nel doubletipo che non possono essere rappresentati decimal- quelli che sono fuori dall'intervallo. Double.Epsilonè 4.94065645841247e-324che non può essere rappresentato in a decimal, ma può in a double.

Tuttavia, all'interno dell'intervallo che il decimale può rappresentare, ha più bit di precisione rispetto ad altri tipi nativi e può rappresentarli senza errori.

Ci sono altri tipi che fluttuano intorno. C'è un BigInteger in C # che può rappresentare un numero intero arbitrariamente grande. Non esiste un equivalente a BigDecimal di Java (che può rappresentare numeri con cifre decimali lunghe fino a 2 32 cifre - che è un intervallo considerevole) esattamente . Tuttavia, se cerchi un po 'in giro puoi trovare implementazioni arrotolate a mano.

Ci sono alcune lingue che hanno anche un tipo di dati razionale che consente di rappresentare esattamente i razionali (in modo che 1/3 sia effettivamente 1/3).


In particolare per C # e la scelta di float o razionale, rimanderò a Jon Skeet dalla pinta mobile decimale in .NET :

La maggior parte delle applicazioni aziendali dovrebbe probabilmente utilizzare decimale anziché float o double. La mia regola empirica è che i valori artificiali come la valuta sono generalmente meglio rappresentati con virgola mobile decimale: il concetto di esattamente 1,25 dollari è del tutto ragionevole, per esempio. Per i valori del mondo naturale, come lunghezze e pesi, i tipi binari a virgola mobile hanno più senso. Anche se esiste un teorico "esattamente 1,25 metri", nella realtà non accadrà mai: sicuramente non sarai mai in grado di misurare le lunghezze esatte, ed è improbabile che esistano anche a livello atomico. Siamo abituati a sostenere una certa tolleranza.


+1 per una spiegazione matematica chiara e concisa. E per rispondere alla versione più generale della domanda posta nel titolo, un esempio di un numero non rappresentabile nella base 10 è 1/3.
Doval,

@Doval Sospetto che ci sia un difetto nel mio ragionamento o nella mia spiegazione che una persona più orientata alla matematica potrebbe sottolineare ... ma penso di essere sulla strada giusta, se è così.

"Relativamente primo" in questo caso significa semplicemente "non un fattore di", giusto? C'è qualche relazione matematica più profonda che mi manca?
Patrick M,

1
Ah, così come lo capisco, n = 15e b = 10non sono relativamente primi ("non condividono fattori positivi comuni (divisori) tranne 1") perché condividono 5 come fattore. La chiave è che non tutti i fattori di 15 (5 e 3) non sono anche fattori di 10. (A parte: c'è una parola per indicare numeri che condividono o non condividono tutti i fattori comuni?) Penso che sia ordinato racchiuso nella tua k, n, mequazione, ma per avvolgermi davvero la testa, avrei bisogno di vedere un grafico 3D. Indipendentemente da ciò, ben meritato +1 a te.
Patrick M,

1
@PatrickM: "A parte: c'è una parola per indicare numeri che condividono o non condividono tutti i fattori comuni?": Qualsiasi numero intero è un fattore di per sé, quindi se tutti i fattori di m sono fattori di n , ne consegue banalmente che m è un fattore di n . Un termine per questo, come ben sai, è fattore . Un altro è divisore .
Ruakh,

6

Una volta usciti dall'intervallo di valori accettabili, la risposta è sì. Detto questo, quasi tutto all'interno della gamma avrà una rappresentazione. Riferimento decimale C # Se non indicato nelle specifiche, i numeri irrazionali non possono essere rappresentati esattamente (ad es. E 1 , pi, radice quadrata di 2, ecc.).

La parola chiave decimale indica un tipo di dati a 128 bit. Rispetto ai tipi a virgola mobile, il tipo decimale ha una maggiore precisione e un intervallo più piccolo, che lo rende adatto per calcoli finanziari e monetari. L'intervallo e la precisione approssimativi per il tipo decimale sono indicati nella tabella seguente.

Precisione: 28-29 cifre significative

1 Grazie a MichaelT per avermi ricordato un altro numero irrazionale.


2
@Magus considera il numero irrazionale e(2.71 ...). Il log naturale - ln (x) è log base e. Pertanto, esistono basi irrazionali e sono utili. La particolare utilità di base pi, non ne sono sicuro - ma ciò non significa che non sia usato da qualche parte.

6
@Max ti stai allontanando sempre di più dalle domande di matematica. Potresti trovare Se un numero è irrazionale in base 10, è irrazionale in altre basi? per essere una lettura utile e un punto di partenza per ulteriori domande sulla teoria dei numeri.

2
1/3 non è irrazionale.
Adam Zuckerman,

2
L'OP ha chiesto della base 10 (dieci). Creare una base numerica di qualsiasi cosa ti permetterà di esprimere qualsiasi cosa come 10. Sulla base dell'articolo di Wikipedia , l'uso di un numero irrazionale come base non lo rende razionale. I numeri razionali possono essere espressi come numeri interi sia per il numeratore che per il denominatore, ripetendo i numeri in un decimale o terminando in modo finito i numeri in un decimale.
Adam Zuckerman,

5
@FrustratedWithFormsDesigner L'irrazionalità non ha nulla a che fare con le basi. Bene, questa è un'esagerazione, ma è l'irrazionalità che ha implicazioni per la rappresentazione del numero in varie basi (ad esempio se ha cifre infinite che non si ripetono), non viceversa. Leggi la domanda math.se collegata sopra: math.stackexchange.com/questions/625473/…

1

Un tipo a virgola mobile base-due sarebbe in grado di rappresentare con precisione molti valori che un tipo di base-dieci della stessa dimensione non potrebbe. Qualsiasi valore che sarebbe esattamente rappresentabile da un tipo base-2 di qualche dimensione sarebbe esattamente rappresentabile in un tipo base-dieci di dimensioni sufficienti. La dimensione richiesta per un tipo a base puramente dieci per rappresentare tutti i valori di un numero binario in virgola mobile dipenderebbe dall'intervallo esponente del tipo binario; centinaia di bit per a floato migliaia per a double.

Detto questo, il Decimaltipo è abbastanza grande che sarebbe stato possibile renderlo utilizzabile come tipo "universale" in grado di contenere il valore di qualsiasi altra primitiva numerica e fornire alcune altre funzionalità aggiuntive oltre (se non altro, utilizzare un bit per indicare se il valore memorizzato è il risultato della conversione di a double, e se quel bit è impostato, utilizzare 64 bit per contenere il valore in questione). Microsoft ha deciso di non farlo, tuttavia. Di conseguenza, la conversione di doublea Decimalin fallirà completamente per valori di grandi dimensioni, causerà l'arrotondamento di valori di piccole dimensioni all'1E-28 più vicino. Inoltre, anche all'interno della gamma dinamica didecimal, il metodo di conversione non "andata e ritorno". Ad esempio, la valutazione di 1,0 / 3,0 come doppio produrrà 0,333333333333333333148, ma la conversione in decimale produrrà 0,33333333333333333m e la conversione in doppio produrrebbe 0,333333333333332321818.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.