Problème de multiplication [Résolu/Fermé]

Signaler
-
Messages postés
609
Date d'inscription
dimanche 17 septembre 2017
Statut
Membre
Dernière intervention
25 février 2019
-
Bonjour,

J'ai actuellement un problème avec ce code
set /a hello=122500*19950
echo %hello%
(ceci est un exemple)
Ceci me retourne "-1851092296" et non "2443875000" ce qui pose un sérieux problème dans mon programme de calcul pour le traçage d'une ellipse qui foire totalement (quand a est au dessus de 300 et b de 127) je mets toujours le code au cas où cela aiderait à l'aide
@echo off
if defined __ goto hello
set __=.
call %0 %* | darkbox
set __=
pause>NUL
goto :eof
:hello
pixelFNT.exe 1
title Draw ellipse Bresenham
mode con cols=1000 lines=1000
REM Sets de base
REM Max 300 127
call:draw_ellipse 500 200 e 0 0
pause>nul
:draw_ellipse
set a=%~1
set b=%~2
set x_pos=%~4
set y_pos=%~5
if %~3 EQU c (
set /a x_pos-=%a%
set /a y_pos-=%b%
)
REM Sets pour calculs
set /a a_carre=%a%*%a%
set /a b_carre=%b%*%b%
set /a a_b=%a%*%b%
set /a dix_b=10*%b%
set /a dix_a=10*%a%
set x=0
set y=%b%
set /a dix_b_carre=%dix_b%*%dix_b%
set /a a_carre_cent_b=%a_carre%*100*%b%
set /a dix_a_carre=%dix_a%*%dix_a%
set /a dix_a_carre_divise_quatre=%dix_a_carre%/4
set /a d_un=%dix_b_carre%-%a_carre_cent_b%+%dix_a_carre_divise_quatre%
REM 1ere phase
:loop_1
set /a x_quatrieme_quadrant=%x%+%a%
set /a y_quatrieme_quadrant=%y%+%b%
set x_premier_quadrant=%x_quatrieme_quadrant%
set /a y_premier_quadrant=%y_quatrieme_quadrant%-(2*%y%)
set /a x_troisieme_quadrant=%x_quatrieme_quadrant%-(2*%x%)
set y_troisieme_quadrant=%y_quatrieme_quadrant%
set x_deuxieme_quadrant=%x_troisieme_quadrant%
set /a y_deuxieme_quadrant=%y_troisieme_quadrant%-(2*%y%)
set /a x_premier_quadrant+=%x_pos%
set /a y_premier_quadrant+=%y_pos%
set /a x_deuxieme_quadrant+=%x_pos%
set /a y_deuxieme_quadrant+=%y_pos%
set /a x_troisieme_quadrant+=%x_pos%
set /a y_troisieme_quadrant+=%y_pos%
set /a x_quatrieme_quadrant+=%x_pos%
set /a y_quatrieme_quadrant+=%y_pos%
echo /g %x_premier_quadrant% %y_premier_quadrant% /a 219 /g %x_deuxieme_quadrant% %y_deuxieme_quadrant% /a 219 /g %x_troisieme_quadrant% %y_troisieme_quadrant% /a 219 /g %x_quatrieme_quadrant% %y_quatrieme_quadrant% /a 219
set /a cent_y=100*%y%
set /a cent_x=100*%x%
set /a cent_y_moins_cinqante=%cent_y%-50
set /a cent_x_plus_cent=%cent_x%+100
set /a a_carre_cent_y_moins_cinqante=%a_carre%*%cent_y_moins_cinqante%
set /a b_carre_cent_x_plus_cent=%b_carre%*%cent_x_plus_cent%
echo %y% %cent_y% %cent_y_moins_cinqante% %a_carre% %a_carre_cent_y_moins_cinqante%> hello.txt
echo %x% %cent_x% %cent_x_plus_cent% %b_carre% %b_carre_cent_x_plus_cent%>> hello.txt
if %a_carre_cent_y_moins_cinqante% LEQ %b_carre_cent_x_plus_cent% goto 2iemephase
set /a deux_cent_x=200*%x%
set /a deux_cent_x_plus_trois_cent=%deux_cent_x%+300
set /a b_carre_deux_cent_x_plus_trois_cent=%b_carre%*%deux_cent_x_plus_trois_cent%
set /a deux_cent_y=200*%y%
set /a deux_cent_y_plus_deux_cent=%deux_cent_y%-200
set /a a_carre_deux_cent_y_plus_deux_cent=%a_carre%*%deux_cent_y_plus_deux_cent%
if %d_un% GEQ 0 goto calcul_1
set /a d_un+=%b_carre_deux_cent_x_plus_trois_cent%
set /a x+=1
goto loop_1
REM 2ieme phase
:2iemephase
set /a dix_x=10*%x%
set /a dix_x_plus_cinq=%dix_x%+5
set /a dix_x_plus_cinq_carre=%dix_x_plus_cinq%*%dix_x_plus_cinq%
set /a b_carre_dix_x_plus_cinq_carre=%b_carre%*%dix_x_plus_cinq_carre%
set /a dix_y=10*%y%
set /a dix_y_moins_dix=%dix_y%-10
set /a dix_y_moins_dix_carre=%dix_y_moins_dix%*%dix_y_moins_dix%
set /a a_carre_dix_y_moins_dix_carre=%a_carre%*%dix_y_moins_dix_carre%
set /a dix_a_carre_b_carre=%dix_a_carre%*%b_carre%
set /a d_deux=%b_carre_dix_x_plus_cinq_carre%+%a_carre_dix_y_moins_dix_carre%-%dix_a_carre_b_carre%
:loop_2
set /a x_quatrieme_quadrant=%x%+%a%
set /a y_quatrieme_quadrant=%y%+%b%
set x_premier_quadrant=%x_quatrieme_quadrant%
set /a y_premier_quadrant=%y_quatrieme_quadrant%-(2*%y%)
set /a x_troisieme_quadrant=%x_quatrieme_quadrant%-(2*%x%)
set y_troisieme_quadrant=%y_quatrieme_quadrant%
set x_deuxieme_quadrant=%x_troisieme_quadrant%
set /a y_deuxieme_quadrant=%y_troisieme_quadrant%-(2*%y%)
set /a x_premier_quadrant+=%x_pos%
set /a y_premier_quadrant+=%y_pos%
set /a x_deuxieme_quadrant+=%x_pos%
set /a y_deuxieme_quadrant+=%y_pos%
set /a x_troisieme_quadrant+=%x_pos%
set /a y_troisieme_quadrant+=%y_pos%
set /a x_quatrieme_quadrant+=%x_pos%
set /a y_quatrieme_quadrant+=%y_pos%
echo /g %x_premier_quadrant% %y_premier_quadrant% /a 219 /g %x_deuxieme_quadrant% %y_deuxieme_quadrant% /a 219 /g %x_troisieme_quadrant% %y_troisieme_quadrant% /a 219 /g %x_quatrieme_quadrant% %y_quatrieme_quadrant% /a 219
if %y% EQU 0 goto:eof
set /a deux_cent_y=200*%y%
set /a deux_cent_y_plus_trois_cent=%deux_cent_y%-300
set /a a_carre_deux_cent_y_plus_trois_cent=%a_carre%*%deux_cent_y_plus_trois_cent%
if %d_deux% LSS 0 goto calcul_2
set /a d_deux-=%a_carre%*%deux_cent_y_plus_trois_cent%
set /a y-=1
goto loop_2
:calcul_1
set /a d_un=%d_un%+%b_carre_deux_cent_x_plus_trois_cent%-%a_carre_deux_cent_y_plus_deux_cent%
set /a x+=1
set /a y-=1
goto loop_1
:calcul_2
set /a deux_cent_x=200*%x%
set /a deux_cent_x_plus_deux_cent=%deux_cent_x%+200
set /a b_carre_deux_cent_x_plus_deux_cent=%b_carre%*%deux_cent_x_plus_deux_cent%
set /a d_deux=%d_deux%+%b_carre_deux_cent_x_plus_deux_cent%-%a_carre_deux_cent_y_plus_trois_cent%
set /a x+=1
set /a y-=1
goto loop_2

(j'utilise pixelfnt.exe et darkbox.exe pour l'affichage)

Merci d'avance,

Programme

1 réponse

Messages postés
609
Date d'inscription
dimanche 17 septembre 2017
Statut
Membre
Dernière intervention
25 février 2019
165
Bonjour,
Je ne connais pas ce langage, mais le résultat obtenu me fait penser à un dépassement de capacité (stack overflow).
Cela se produit quand la valeur excède la limite maximale du type.

Par exemple, la valeur maximale pour un int codé sur 32 bits est 2,147,483,647.
Ici, le résultat est 2,443,875,000 donc il dépasse cette valeur.

Quel type de variable utilisez-vous pour stocker ces nombres ?
Le type du résultat est-il suffisant pour stocker un nombre aussi grand ?
Cordialement
1
Merci

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

CCM 65492 internautes nous ont dit merci ce mois-ci

En batch, une variable peut être utilisée afin de stoquer autant un nombre que du texte. En effet c'est surement cela auriez vous une solution?
Messages postés
609
Date d'inscription
dimanche 17 septembre 2017
Statut
Membre
Dernière intervention
25 février 2019
165
https://stackoverflow.com/questions/11546020/can-batch-files-not-process-large-numbers

Cette personne a les mêmes problèmes que vous et on lui répond qu'en batch ça n'est pas possible à cause du fait que cmd.exe soit une application 32bits... (a vérifier)
Messages postés
609
Date d'inscription
dimanche 17 septembre 2017
Statut
Membre
Dernière intervention
25 février 2019
165
Une possible solution ici mais elle a l'air assez complexe:

https://superuser.com/questions/827044/batch-script-32-bit-limitation-of-integer
>
Messages postés
609
Date d'inscription
dimanche 17 septembre 2017
Statut
Membre
Dernière intervention
25 février 2019

Merci pour vos réponses ! J'ai résolu mon problème grace à la votre via ceci http://www.robvanderwoude.com/files/multiply_3rdparty_bat.txt

J'ai modifié le code pour qu'il ne soit pas si visuellement agressif et qu'on puisse l'exécuté plusieurs fois à la suite (car des variables nécessitaient d'être resettées)
@echo OFF
setlocal enableextensions
setlocal enabledelayedexpansion
call:multiplication 122500 19950
echo %resultat%
call:multiplication 5203216584 165503216
echo %resultat%
pause>nul
:multiplication

set num1cnt=
set num2cnt=
set resultat=
set tmp=
set cnt=
set colcnt=
set num1=%1
set num2=%2
for /l %%a in (1,1,2) do (
for /l %%b in (0,1,9) do (
set num%%a=!num%%a:%%b=%%b !
)
)
for %%a in (!num1!) do set /a num1cnt+=1 & set _!num1cnt!num1=%%a
for %%a in (!num2!) do set /a num2cnt+=1 & set _!num2cnt!num2=%%a
if !num1cnt! EQU 1 if !num2cnt! EQU 1 (
set /a resultat=!num1! * !num2!
goto:eof
)
for /l %%b in (!num2cnt!,-1,1) do (
for /l %%a in (!num1cnt!,-1,1) do (
set /a tmp=!_%%bnum2! * !_%%anum1! !plus! !co!
set co=
set plus=
if !tmp! GTR 9 set co=!tmp:~0,1!& set tmp=!tmp:~-1!& set plus=+
set num3_%%b=!num3_%%b!!spc!!tmp!
set spc=
set tmp=
)
if defined co set num3_%%b=!num3_%%b! !co!& set co=& set plus=
set num3_%%b=!zero!!num3_%%b!
set zero=0!spc1!!zero!
set spc1=
for %%a in (!num3_%%b!) do (
set /a cnt+=1
for %%c in (!cnt!) do set num4_%%c=!num4_%%c!%%a+
)
set cnt=
)
for /f %%a in ('set num4') do set /a colcnt+=1
for /l %%a in (1,1,!colcnt!) do set /a num5_%%a=!num4_%%a:~0,-1!
for /l %%a in (1,1,!colcnt!) do (
if defined co set /a num5_%%a=!num5_%%a! + !co!
set co=
if !num5_%%a! GTR 9 (
set co=!num5_%%a:~0,-1!
set num6=!num5_%%a:~-1!!num6!
) else (
set num6=!num5_%%a!!num6!
)
set resultat=!co!!num6!
)
goto:eof
Messages postés
609
Date d'inscription
dimanche 17 septembre 2017
Statut
Membre
Dernière intervention
25 février 2019
165
Content que ça fonctionne, n'hésitez pas à mettre le sujet en résolu :)
Bonne journée