+ Répondre à la discussion
Affichage des résultats 1 à 3 sur 3
  1. #1
    Membre chevronné Avatar de edfed
    être humain
    Inscrit en
    décembre 2007
    Messages
    471
    Détails du profil
    Informations professionnelles :
    Activité : être humain

    Informations forums :
    Inscription : décembre 2007
    Messages : 471
    Points : 628
    Points
    628

    Par défaut bin2fdec -padding pour faire 12 caractères

    comme les codes precedement postés ici, ceci est un aide mémoire.

    celui ci couvre le code necessaire à la convertion d'un nombre decimal en une chaine de caractères terminée par 0.

    l'algo est de mise en oeuvre super simple, et permet entre autre de faire dans la virgule fixe, et la virgule flottante (avec des adaptations evidement).

    la chaine de base, ici str db "0000.000", contient un point décimal permettant d'interpreter eax en tant que valeur en virgule fixe, à 3 decimales apres la virgule.

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
     
    mov eax,[valeur]
    mov ebx,str.end
    mov edi,str
    call fixeddecimal
    ;ebx = chaine de caractère
    mov eax,ebx
    call printf ;afficher la chaine pointée par eax
    la structure invoquée par cette fonction est comme suit:
    Code :
    1
    2
    3
    4
     
    valeur dd ?
    str db "0000.000"
    .end db 0
    et enfin, la fonction en elle même
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
     
    fixeddecimal:
            mov ecx,10
    .loop:
            dec ebx
            cmp byte[ebx],'.'
            jne @f
            dec ebx
    @@:
            cmp ebx,edi
            jl .end
            xor edx,edx
            div ecx
            or edx,edx
            jne @f
            or eax,eax
            jne @f
            mov dl,' '-'0'
    @@:
            add dl,'0'
            mov [ebx],dl
            jmp .loop
    .end:
            ret
    Vous voyez, ce n'est pas bien compliqué.

    Et si l'on veut juste un nombre sans point décimal, il suffit de ne pas déclarer de point dans la chaine de destination.

    Personnelement, j'utilise cette fonction pour toutes les conversions binaire vers décimal, avec ou sans virgule fixe.
    l'avantage est certain car il permet de n'avoir qu'une seule fonction pour ces deux actions.

    pour la virgule flottante, il y aura donc lieu de proceder à une conversion.
    tou d'abord, determiner la position de la virgule avec la FPU (ou SSE), multiplier par la puissance necessaire à la disparition de la virgule. et enfin, convertir en binaire (fist)
    suite à ça, il y aura lieu de creer la chaine de reception, avec le point decimal à la bonne position, et le tour est joué.

    il est aussi possible, à moindre frais, d'utiliser le format BCD de la FPU pour charger directement un nombre décimal, et juste extraire chaque nibble, puis aditionner la valeur du "0" ascii, et enfin, l'envoyer dans la chaine.

  2. #2
    Membre confirmé

    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    juin 2007
    Messages
    49
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : juin 2007
    Messages : 49
    Points : 291
    Points
    291

    Par défaut

    Moi j'ai ça :
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
     
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;; nombreVersChaine													;;
    ;;------------------------------------------------------------------;;
    ;; Ecrit dans la chaîne pointée par EDI le nombre contenu dans EAX	;;
    ;; si CL est à un, on écrit un caractère terminal					;;
    ;; CH contient le nombre minimal de caractères à utiliser			;;
    ;; EBX contient la base												;;
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    nombreVersChaine:
    	push 	edx
    	push 	ecx
    	xor		cl, cl
    .stocke_digit:
    	xor 	edx, edx
    	div 	ebx
    	push 	edx 			; Sauve le reste dans la pile
    	inc 	cl
    	or 		eax, eax		; Si le quotient n'est pas nul
    	jne 	.stocke_digit	; on recommence
    ;Les digits sont stockés dans la pile
    .ajout_zero:
    	cmp 	ch, cl
    	jbe		.clearCH
    	push 	' '-'A'+10		; Nombre magique permettant de remplir avec des espaces
    	inc 	cl
    	jmp 	.ajout_zero
    .clearCH:
    	xor 	ch, ch
    ;Affichage du chiffre : On en affiche au moins un : zéro
    .affiche_digit:
    	pop 	eax
    	cmp 	al, 10
    	jae 	.dixPlus
    	add 	al, '0'
    	stosb 					; met AL dans l'octet pointé par EDI et incrémente EDI
    	jmp 	.boucle_digit
    .dixPlus:					; Pour les bases à plus de 10 chiffres, on utilise l'alphabet
    	add 	al, 'A' - 10
    	stosb
    	jmp 	.boucle_digit
    .boucle_digit:
    	loop 	.affiche_digit
    	pop 	ecx 			; on récupère le paramètre cx
    	test 	cl, 0b1 		; s'il est à 1, on écrit un caractère terminal
    	jz 		.depile
    	mov 	byte [edi], 0
    .depile:
    	pop 	edx
    ret
     
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;;	Fin nombreVersChaine											;;
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    Ca écrit dans n'importe quelle base, j'ai pas testé au-delà de la base 36 où il peut y avoir des problèmes. Ca ne fait pas les nombres à virgule flottante, ça termine la chaîne au besoin et ca complète une chaîne si spécifié.

  3. #3
    Membre chevronné Avatar de edfed
    être humain
    Inscrit en
    décembre 2007
    Messages
    471
    Détails du profil
    Informations professionnelles :
    Activité : être humain

    Informations forums :
    Inscription : décembre 2007
    Messages : 471
    Points : 628
    Points
    628

    Par défaut

    bein, pour n'importe quelle base, suffit de remplacer 10 par la base.
    si en plus BASE est entrée dans ecx au moment d'appeler cette fonction
    Code :
    1
    2
    3
    4
    5
    6
     
    mov ecx,base
    mov eax,num
    mov ebx,finstring
    mov edi,string
    call fixedbase
    ...
    methode très maladroite, mais bon, quand on aime passer les paramètres par les registres, on ne compte pas voyons.

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
     
    fixedBASE:
            push ecx
    .loop:
            pop ecx
            push ecx
            dec ebx
            cmp byte[ebx],'.'
            jne @f
            dec ebx
    @@:
            cmp ebx,edi
            jl .end
            xor edx,edx
            div ecx
            or edx,edx
            jne @f
            or eax,eax
            jne @f
            mov dl,' '-'0'
    @@:
            add dl,'0'
            mov [ebx],dl
            jmp .loop
    .end:
            ret
    tout ça pour juste convertir en décimal, tant qu'a faire, pour un bon compromis (chose due), on crée un truc par dessus pour prendre le controle centralisé des bases...

    par exemple, un drapeau, mais là, on complique le code... pour rien au final car chaque base permet ses propres algorythmes optimisés.
    la base 10 est une de celles qui ne donne pas trop dans l'optimisation. sauf peut etre avec les instructions AAM, AAD. qui permettent de diviser et multiplier par 10, ou tout autre base.

    non mais ça me convenait parfaitement comme code pour convertir du decimal, pour le binaire, pas besoin de division, pour l'hexa non plus.
    et je vois pas de base autre que 10 à utiliser dans la vie de tout les jours.

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •