Сборка MIPS (MARS 4.5): арифметрия с плавающей запятой c ответ странный - PullRequest
1 голос
/ 28 мая 2020

Я делаю программу MIPS для вычисления 5.4xy - 12.3y + 18.23x - 8.23y, где x и y - входные данные с консоли. Однако результат получился слишком странным. Вот мой код:

.data
    promptX: .asciiz "Enter x: \n"
    promptY: .asciiz "Enter y: \n"
    result: .asciiz "Result: "
    first: .float 5.40
    second: .float -12.30
    third: .float 18.23
    fourth: .float -8.23
.text

    # Print prompt to input x
    li $v0, 4
    la $a0, promptX
    syscall

    # Get x, store in f2
    li $v0, 7
    syscall
    mov.d $f2, $f0

    # Prompt input y
    li $v0, 4
    la $a0, promptY
    syscall

    # Get y, store in f4
    li $v0, 7
    syscall
    mov.d $f4, $f0


    # f6 = xy
    mul.d $f6, $f2, $f4

    # load 5.4 to f8
    lwc1 $f8, first

    # f6 = 5.4xy
    mul.d $f6, $f6, $f8

    # load -12.3 to f8
    lwc1 $f8, second
    # f8 = -12.3y
    mul.d $f8, $f8, $f4


    # f6 = 5.4xy - 12.3y
    add.d $f6, $f6, $f8

    # load 18.23 to f8
    lwc1 $f8, third
    # f8 = 18.23x
    mul.d $f8, $f8, $f2
    # f6 = 5.4xy - 12.3y + 18.23x
    add.d $f6, $f6, $f8

    # load -8.23 to f8
    lwc1 $f8, fourth

    # f6 = 5.4xy - 12.3y + 18.23x + (- 8.23)
    add.d $f12, $f6, $f8

    # Print answer
    li $v0, 4
    la $a0, result
    syscall

    li $v0, 2
    syscall


    # End program
    li $v0, 10
    syscall

Когда я ввожу x = 2,13 и y = 2,13, он возвращает 1,26719E-10, где должно быть 28,90016. Я перепроверяю код много раз, но до сих пор не знаю почему. Любая помощь приветствуется.

Ответы [ 2 ]

2 голосов
/ 28 мая 2020

Это будет работать:

.data
    promptX: .asciiz "Enter x: \n"
    promptY: .asciiz "Enter y: \n"
    result: .asciiz "Result: "
    first: .double 5.40
    second: .double -12.30
    third: .double 18.23
    fourth: .double -8.23
.text

    # Print prompt to input x
    li $v0, 4
    la $a0, promptX
    syscall

    # Get x, store in f2
    li $v0, 7
    syscall
    mov.d $f2, $f0

    # Prompt input y
    li $v0, 4
    la $a0, promptY
    syscall

    # Get y, store in f4
    li $v0, 7
    syscall
    mov.d $f4, $f0


    # f6 = xy
    mul.d $f6, $f2, $f4
    #mul.d $f2, $f4, $f6

    # load 5.4 to f8
    l.d $f8, first

    # f6 = 5.4xy
    #mul.d $f6, $f6, $f8
    mul.d $f6, $f6, $f8

    # load -12.3 to f8
    l.d $f8, second
    # f8 = -12.3y
    mul.d $f8, $f8, $f4


    # f6 = 5.4xy - 12.3y
    add.d $f6, $f6, $f8

    # load 18.23 to f8
    l.d $f8, third
    # f8 = 18.23x
    mul.d $f8, $f8, $f2
    # f6 = 5.4xy - 12.3y + 18.23x
    add.d $f6, $f6, $f8

    # load -8.23 to f8
    l.d $f8, fourth

    # f6 = 5.4xy - 12.3y + 18.23x + (- 8.23)
    add.d $f12, $f6, $f8

    # Print answer
    li $v0, 4
    la $a0, result
    syscall

    li $v0, 3

    syscall


    # End program
    li $v0, 10
    syscall

Вы смешивали точность. Я сделал все вдвое. В конце концов, вы пытались напечатать число с плавающей запятой с 2 ​​в v0, вам нужно 3 в v0, чтобы напечатать double.

Другая проблема, которую я заметил, заключалась в том, как вы загружали данные из памяти в свои регистры. Я переключил их на ld, и значения были загружены правильно.

2 голосов
/ 28 мая 2020

Вы смешиваете числа с одинарной и двойной точностью.

  • Коэффициенты в разделе .data: float
  • Вы читаете входные данные как double
  • You загружайте коэффициенты (используя lwc1) как float
  • Вы выполняете вычисления (mul.d и add.d) как double
  • Вы печатаете результат как float

Переключите все на ту же точность, и ваш код будет работать правильно.

...