1

Je travaille sur un devoir, où nous sommes supposés convertir un int en float via des opérations au niveau du bit. Le code suivant fonctionne, sauf qu'il rencontre des arrondis. Ma fonction semble toujours arrondir vers le bas, mais dans certains cas, il devrait arrondir vers le haut.Points d'arrondi lors de la conversion au flottant bitwise

Par exemple 0x80000001 doit être représenté comme 0xcf000000 (exponent 31, mantisse 0), mais ma fonction renvoie 0xceffffff. (exposant 30, mantisse 0xffffff).

Je ne sais pas comment continuer à résoudre ces problèmes d'arrondi. Quelles mesures dois-je prendre pour que cela fonctionne?

unsigned float_i2f(int x) { 
    if(x==0) return 0; 
    int sign = 0; 
    if(x<0) { 
    sign = 1<<31; 
    x = -x; 
    } 
    unsigned y = x; 
    unsigned exp = 31; 
    while ((y & 0x80000000) == 0) 
    { 
    exp--; 
    y <<= 1; 
    } 
    unsigned mantissa = y >> 8; 

    return sign | ((exp+127) << 23) | (mantissa & 0x7fffff); 
} 

double possible de this, mais la question est mal répondu.

+1

1 << 31 est un comportement indéfini. Je recommande fortement d'éviter les opérations de décalage avec des opérandes signés, si possible. – gnasher729

+1

x = -x est un comportement indéfini si x = INT_MIN et INT_MIN! = - INT_MAX. – gnasher729

+0

1 << 31 n'est pas un comportement non défini, il est simplement 1 avec 31 zéro suivant, ou en d'autres termes, INT_MAX. Vous pourriez le confondre avec 1 << 32, qui est en fait indéfini. – jamiees2

Répondre

0

Vous ignorez évidemment les 8 bits les plus faibles de y lorsque vous calculez la mantisse. La règle habituelle est appelée "arrondi au plus proche pair": Si les 8 bits les plus bas sont> 0x80 alors augmenter la mantisse de 1. Si les 8 bits les plus bas sont = 0x80 et le bit 8 est 1, alors augmenter la mantisse par 1. Dans les deux cas, si la mantisse devient> = 0x1000000, déplacez la mantisse vers la droite et augmentez l'exposant.

+0

Merci beaucoup! Cela fonctionne enfin! – jamiees2

Questions connexes