[JAVA] Obtenons la représentation interne d'un nombre à virgule flottante

C'est proche, Kon'nichiwa! Cette fois, je vais vous présenter comment obtenir la représentation interne des nombres à virgule flottante.

1. Qu'est-ce qu'un nombre à virgule flottante?

Un nombre à virgule flottante est un nombre qui représente une fraction avec une partie de code, une partie d'exposant et une partie incorrecte. Dans de nombreux langages de programmation, la norme appelée IEEE 754 a été adoptée et la représentation interne est organisée dans l'ordre de la partie de code, de la partie de l'exposant et de la partie incorrecte à partir du haut.

f1-1.PNG

2. Obtenons la représentation interne des nombres à virgule flottante par programmation

Ici, nous allons créer des programmes qui acquièrent la représentation interne du type virgule flottante simple précision (type float). Les langages sont C, C ++, C #, VB.NET et Java.

2.1 Méthode utilisant un corps commun (langage C, C ++)

En langage C et C ++, un ** corps commun ** composé de ** une variable de type float ** et une ** variable de type int ** avec la même taille de données que le type float est utilisé. Étant donné que chaque membre de l'union se trouve dans la même zone de mémoire, vous pouvez obtenir la représentation interne de la valeur de type float à partir du membre de type int en mettant un nombre réel dans le membre de type float.

float-bin.c


#include <stdio.h>

int main( void ) {

    /*Étant donné que la taille des données du type float est de 32 bits, elle est combinée avec le type entier 32 bits (int).*/
    union { float f; int i; } a;
    int i;
    a.f = -2.5f;

    printf( "%f ( %08X )\n", a.f, a.i );
    
    /*Afficher une colonne de bits*/
    for( i = 31; i >= 0; i-- ){
        printf( "%d", ( a.i >> i ) & 1 );
    }
    printf( "\n" );
    
    /*Extraire la partie exposant (1 bit), la partie exposant (8 bits) et la partie incorrecte (23 bits)*/
    printf( "Partie de code: %X\n", ( a.i >> 31 ) & 1 );
    printf( "Partie d'index: %X\n", ( a.i >> 23 ) & 0xFF );
    printf( "Partie formelle: %X\n", a.i & 0x7FFFFF );

    return 0;
}

** Résultat de l'exécution ** -2.500000 ( C0200000 ) 11000000001000000000000000000000 Partie de code: 1 Partie index: 80 Partie formelle: 200000

2.2 Méthode utilisant les fonctions de classe (C #, VB.NET, Java)

C # et VB.NET utilisent la ** classe BitConverter ** du .NET Framework. Vous pouvez utiliser la méthode ** BitConverter.GetBytes ** pour convertir une fois une valeur de type float en un tableau de type byte, puis utiliser la méthode ** BitConverter.ToInt32 ** pour obtenir la représentation interne de la valeur de type float.

float-bin.cs


using System;

public class Program{
    public static void Main(){
        
        float f = -2.5f;
        // BitConverter.La méthode ToInt32 prend un tableau d'octets et le premier index à convertir en arguments
        int i = BitConverter.ToInt32( BitConverter.GetBytes( f ), 0 );
        Console.WriteLine( "{0:F} ( {1:X8} )", f, i );
        
        //Affiche une colonne de bits
        for( int j = 31; j >= 0; j-- ){
            Console.Write( ( i >> j ) & 1 );
        }
        Console.WriteLine();
        
        //Extraire la partie exposant (1 bit), la partie exposant (8 bits) et la partie incorrecte (23 bits)
        Console.WriteLine( "Partie de code: {0:X}", ( i >> 31 ) & 1 );
        Console.WriteLine( "Partie d'index: {0:X}", ( i >> 23 ) & 0xFF );
        Console.WriteLine( "Partie formelle: {0:X}", i & 0x7FFFFF );
    }
}

float-bin.vb


Module Module1

    Sub Main()
		
	Dim f As Single = -2.5f
        ' BitConverter.La méthode ToInt32 prend un tableau d'octets et le premier index à convertir en arguments
        Dim i As Integer = BitConverter.ToInt32( BitConverter.GetBytes( f ), 0 )
        Console.WriteLine( "{0:F} ( {1:X8} )", f, i )
        
        'Afficher une colonne de bits
        Dim j As Integer
        For j = 31 To 0 Step -1
            Console.Write( ( i >> j ) And 1 )
        Next
        Console.WriteLine()
        
        'Extraire la partie exposant (1 bit), la partie exposant (8 bits) et la partie incorrecte (23 bits)
        Console.WriteLine( "Partie de code: {0:X}", ( i >> 31 ) And 1 )
        Console.WriteLine( "Partie d'index: {0:X}", ( i >> 23 ) And &HFF )
        Console.WriteLine( "Partie formelle: {0:X}", i And &H7FFFFF )

        
    End Sub

End Module

Java utilise la ** classe Float **. Vous pouvez obtenir la représentation interne d'une valeur de type float avec la méthode ** Float.floatToIntBits **.

float-bin.java


public class Main {
    public static void main(String[] args) throws Exception {
        
        float f = -2.5f;
        int i = Float.floatToIntBits( f );
        System.out.printf( "%f ( %08X )\n", f, i );
        
        //Afficher une colonne de bits
        for( int j = 31; j >= 0; j-- ){
            System.out.printf( "%d", ( i >> j ) & 1 );
        }
        System.out.println();
        
        //Extraire la partie exposant (1 bit), la partie exposant (8 bits) et la partie incorrecte (23 bits)
        System.out.printf( "Partie de code: %X\n", ( i >> 31 ) & 1 );
        System.out.printf( "Partie d'index: %X\n", ( i >> 23 ) & 0xFF );
        System.out.printf( "Partie formelle: %X\n", i & 0x7FFFFF );
        
    }
}

2.3 Méthode utilisant la conversion de cast de pointeur (langage C, C ++, C #)

En langage C, C ++ et C #, vous pouvez obtenir la représentation interne d'une valeur de type float en convertissant ** un pointeur de type float en un pointeur de type int **.

float-binptr.c


#include <stdio.h>

int main( void ) {

    float f = -2.5f;
    int i = *( ( int* )&f ), j;
    printf( "%f ( %08X )\n", f, i );
    
    /*Afficher une colonne de bits*/
    for( j = 31; j >= 0; j-- ){
        printf( "%d", ( i >> j ) & 1 );
    }
    printf( "\n" );
    
    /*Extraire la partie exposant (1 bit), la partie exposant (8 bits) et la partie incorrecte (23 bits)*/
    printf( "Partie de code: %X\n", ( i >> 31 ) & 1 );
    printf( "Partie d'index: %X\n", ( i >> 23 ) & 0xFF );
    printf( "Partie formelle: %X\n", i & 0x7FFFFF );

    return 0;
}

En C #, les pointeurs sont traités comme du code unsafe et doivent être compilés avec l'option "** / unsafe **".

float-binptr.cs


using System;

public class Program {
	//Lorsque vous traitez avec du code non sécurisé, ajoutez le mot clé «unsafe».
	public unsafe static void Main() {

		float f = -2.5f;
		int i = *( ( int* )&f );
		Console.WriteLine( "{0:F} ( {1:X8} )", f, i );

		//Afficher une colonne de bits
		for( int j = 31; j >= 0; j-- ) {
			Console.Write( ( i >> j ) & 1 );
		}
		Console.WriteLine();

		//Extraire la partie exposant (1 bit), la partie exposant (8 bits) et la partie incorrecte (23 bits)
		Console.WriteLine( "Partie de code: {0:X}", ( i >> 31 ) & 1 );
		Console.WriteLine( "Partie d'index: {0:X}", ( i >> 23 ) & 0xFF );
		Console.WriteLine( "Partie formelle: {0:X}", i & 0x7FFFFF );
	}
}

3. Conclusion

Cette fois, j'ai créé un programme pour obtenir la représentation interne du type float en utilisant plusieurs langages comme exemples. Bien sûr, vous pouvez obtenir la représentation interne de la même manière avec le type double.

Par exemple, pourquoi ne pas l'utiliser lorsque vous regardez le calcul des nombres à virgule flottante dans une classe informatique.

À la prochaine!

Recommended Posts

Obtenons la représentation interne d'un nombre à virgule flottante
Comment obtenir n'importe quel numéro de chiffre à partir de 2 chiffres ou plus! !!
Qu'est-ce qu'une virgule flottante?
Un exemple simple du modèle MVC
[Swift] Comment obtenir le nombre d'éléments dans un tableau (super basique)