Velocità di esecuzione delle funzioni ceil(),round(),floor() - pagina 3

 
Nikolai Semko:

Sì, ma se:

allora va bene.

Resta da vedere se va bene per qualsiasi numero x
 

A100:

void OnStart()
{
        Print( (int)(3.0001 + 0.999999999999999)); //все равно 4
        Print( floor(3.00001));                    //3
}




Non capisco. Qual è il problema?

 
A100:
Resta da vedere se andrà bene per qualsiasi numero x

Naturalmente non lo farà...

Dopo tutto, se questo accade

double x=3;
x=x+0.1;
x=x+0.1;
x=x+0.1;
x=x+0.1;
if (x!=3.4) Print("oppps..."); // oppps...

allora, le domande non sono né per me né per questa idea.

 
Nikolai Semko:
Qual è il problema?
void OnStart()
{
        double d =  16 + 0.999999999999999;
        Print( (int)(d + 0.999999999999999)); //18
        Print( (int)ceil( d ));               //17
}
 
A100:

vedere il mio post precedente

 
Nikolai Semko:
allora, le domande non sono né per me, né per questa idea.
floor(), ceil(), round() sono lì per evitare domande
 

Penso che tutti questi difetti di cui sopra sono al di là della portata dell'uso pratico di questa soluzione per accelerare l'arrotondamento dei numeri interi positivi, perché poche persone hanno bisogno di precisione a livello di 16 cifre. E questi bug nascono da ogni sorta di overflow ai livelli di punti del compilatore stesso.

 
A100:
Floor(), ceil(), round() sono lì per quello scopo - quindi non ci sono domande

Non vi sto vietando di usarli. Siete i benvenuti a usarli. Li userò io stesso. Ma se creo un algoritmo dove la velocità è importante, userò questa variante di arrotondamento tenendo conto di tutte le sfumature di questo metodo. Penso che sarà utile per altri programmatori sapere dell'esistenza di questa alternativa. La discussione è esattamente ciò che dobbiamo sapere sulle sfumature di questo metodo di arrotondamento. Vi ringrazio molto per questo. Non ho ragione?

 
Nikolai Semko:

DBL_MIN eDBL_EPSILON non funzionano - troppo piccoli. Forse ha senso lasciare 0,99999999999999999999 (16 nove - il numero massimo di cifre dopo il punto decimale nel doppio)

Quindi, DBL_EPSILON è 16 cifre decimali:2.2204460492503131e-016.

Nel tuo caso, ne ottieni effettivamente uno, dato che la differenza è solo 1e-16, che è 2 volte meno di epsilon.

 
Alexey Navoykov:

Quindi DBL_EPSILON è 16 cifre decimali:2.2204460492503131e-016

E nel tuo caso ne ottieni effettivamente uno, dato che la differenza è solo 1e-16, che è 2 volte meno di epsilon.


Sì, l'ho capito, ma non funziona. Si scopre che non funziona nemmeno con 16 nove (strano, prima sembrava funzionare). Funziona solo con 15 nove.

double x=3;
int Y=(int)ceil(x);
Print(Y);                         // 3
Y=(int)(x+0.999999999999999); 
Print(Y);                         // 3  (15 9-ток)
Y=(int)(x+0.9999999999999999);
Print(Y);                         // 4  (16 9-ток)
Y=(int)(x+1-DBL_EPSILON);
Print(Y);                         // 4