James Corin
James Corin

Reputation: 35

How to make a negative number positive in MIPS?

Basically the title. I have a negative number in MIPS ISA and I want to make it positive - what is the best way to achieve it? Do I change the sign bit or something? Not entirely sure which route to take here.

For context, I'm trying to divide by 2 to get the number down to just 1, but this isn't possible if the nubmer is negative so I want to make it positive first in order to achieve this.

Upvotes: 2

Views: 10118

Answers (1)

Martin Rosenau
Martin Rosenau

Reputation: 18503

I'd like to give some additional information (because Jester already gave the correct answer):

Do I change the sign bit or something?

There are different ways how negative numbers are stored:

  • Two's complement
    This is the most common way integer numbers are stored because on most CPUs (including MIPS) integer operations (like addition, subtraction) will automatically give the correct result when using two's complement.

  • One's complement
    This way of storing numbers is often used in the checksum calculation rules for internet protocols (IPv4, TCP, UDP...)

  • Absolute value and sign bit
    Floating point numbers are typically stored this way.

Of course what you have to do depends on what kind of numbers you are processing.

How to make a negative number positive in MIPS?

  • Negative numbers are stored as two's complement (most likely for integers):
    As Jester already wrote: Calculate 0-x with subu $v0, $zero, $a0.

  • You are calculating checksums for the internet (one's complement):
    In this case you have to invert all bits. The best option on MIPS is nor $v0, $zero, $a0.
    You could instead x xor (-1) or (-1)-x. On MIPS CPUs, the value (-1) can be generated by one subiu instruction. (But xori uses an unsigned 0..65535 immediate.)

  • You are processing floating point numbers by using integer instructions and want to invert the sign:
    In this case you have to change the sign bit.
    This is done using x xor 0x80000000.
    On MIPS CPUs, you can generate the constant 0x80000000 using one lui instruction.

    (You would do this if you have a CPU without floating-point support and you have to emulate floating-point operations using integer operations. If you have a CPU with floating-point support, you would normally not do this. However, you could also do this if you first copy the floating-point register to an integer register using mfc1 and after the operation you copy the value back using mtc1. Thanks @Alain Merigot for the annotation.)

  • You have a MIPS CPU or a MIPS emulator with floating-point support and want to negate a floating-point number:
    You can use the instructions neg.s (32-bit floating point) or neg.d (64-bit floating point) to negate a number.

See what MIPS GCC does for all 3 of these, for integer inputs: https://godbolt.org/z/ca2nUE.

Upvotes: 2

Related Questions