# Mixed signed/unsigned remainder operation

## Recommended Posts

Hi All,

I am bit confused about the following dout result:

```sc_out<sc_int<8> >  dout;
sc_int<8>         din1=0x80;
sc_uint<4>        din2=0x9;

dout.write(din1 % din2);
```

dout=5;

I know that I am mixing sizes and signed/unsigned but I am intrigued what causes the result to be 5.

I was expecting either -128%9=-2 (or -128%-7=-2). If din1 is reduce to 4 bits then I would expected -1%9=-1 or 0.

Thanks.

##### Share on other sites

The answer is slightly more complex than you might think.

1. Arithmetic operations on sc_(u)int<> are performed on 64-bit accuracy internally

This is by design, see IEEE 1666-2011, Sections 7.5.2.6, 7.5.3.6.  The limited-precision integer types have a conversion operator to their C++ representation (sc_dt::(u)int64) and the arithmetics are performed according to rules of the C++ standard.

2. Signed modulo expressions in C++ are implementation-defined

Quote from ISO/IEC 14882:2003(E), 5.6.(4) (formatting and highlighting by me):

[T]he binary % operator yields the remainder from the division of the first expression by the second. If the second operand of / or % is zero the behavior is undefined; otherwise (a/b)*b + a%b is equal to a. If both operands are nonnegative then the remainder is nonnegative; if not, the sign of the remainder is implementation-defined.

3. C++ integer promotion rules will give you an unsigned operation anyway

Integer arithmetics in C++ are subject to operand promotion rules to determine the appropriate common type for the computation (called usual arithmetic conversions).  In case of mixed signed and unsigned 64-bit types, this will usually be a 64-bit unsigned type.  Details can be found in the C++ standard as well, see clause 5(9).  Note: in C++11, the wording has been slightly extended to explicitly cover 64-bit integer types.

Hope that helps,
Philipp

## Create an account

Register a new account