sfix representation for negative numbers (reading negative decimal numbers from a file)

81 views
Skip to first unread message

Idoia Gamiz

unread,
Mar 16, 2021, 6:55:24 AM3/16/21
to SPDZ/SCALE-MAMBA Discussion Group
Hi,
I am trying to read decimal numbers from a file. In order to do this  I have created a program similar to the  float_to_int.py of the Mamba programming tutorial.
.
The idea is to take the number and to give its sfix representation.
For positive numbers it works fine, for example the number '12.5023' is converted into the integer 13109612 and the correct result is printed.  [ 12.5023 = 13109612 * 2^(-20), as explained in the documentation ]

But when I try to do it with a negative number it doesn't work. For '-12.5023' I get -13109612, but this does not output the correct result. I am using the prime number 340282366920938463463374607431768211507,  how can I fix it?

Code example:
n=2
data=sfix.Array(2)
@for_range(n)
def Data(i):
  data[i] = sfix(sint.get_private_input_from(0))
print_ln('Print 12.5023 and -12.5023: \n')
@for_range(n)
def range_body(i):
  print_str(' %s',data[i].reveal())

I get the output:
12.5023       -273.6

Thank you in advance,

Idoia

Douglas Li

unread,
Mar 16, 2021, 7:29:38 AM3/16/21
to Idoia Gamiz, SPDZ/SCALE-MAMBA Discussion Group
Maybe try with sfix.load_int. 

--
You received this message because you are subscribed to the Google Groups "SPDZ/SCALE-MAMBA Discussion Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to spdz+uns...@googlegroups.com.
To view this discussion on the web, visit https://groups.google.com/d/msgid/spdz/55c9c98e-7a44-41de-a78f-b3b1fda228e0n%40googlegroups.com.

Idoia Gamiz

unread,
Mar 16, 2021, 8:00:42 AM3/16/21
to SPDZ/SCALE-MAMBA Discussion Group
Do you mean data[i] = sfix.load_sint(sint.get_private_input_from(0))?
That doesn't work either, the output is:      526700     -1.67772e+06

As far as I know sfix.load_sint must be used when your input is an integer. Regarding that, I also have problems when the integers are too large, as in this case with 13109612.

Anyway, I just realized that with integers I also have problems when they are negatives.
For integers 131, -131 and replacing sfix.load_sint(sint.get_private_input_from(0)) in the previous code I get:    131     -2869.

Could it be related to the way I have defined the IO class, or does it happens to everyone?

Thank you very much anyway.

Nigel Smart

unread,
Mar 16, 2021, 8:10:04 AM3/16/21
to sp...@googlegroups.com
get_private_input loads an sint value, so an integer mod p.

You then load it into the sfix. Recall an sfix is defined as a
value mod p, whose value is in a certain range, when you
think of this value as an integer
   - This is MUCH more explicit in the new Rust based language
   - But in Mamba you need to do the mental contortion yourself.

Thus you will have a problem as the sint value needs to be
normalized to get it to work correctly, i.e. the value you read
in does not really correspond to how SCALE holds sfix values.

Thus reading sfix values from external places is problematic
  - Even with the Rust language.

Would suggest [for safety] having your external file format
as...
   positive value*2^F    sign as 0/1
Then read these values in as (x,s) and then compute
    a=(2*s-1)*(x)

Nigel

titouan...@gmail.com

unread,
Mar 16, 2021, 8:17:50 AM3/16/21
to SPDZ/SCALE-MAMBA Discussion Group
Your issue seems to be due to how the Input_Output_Simple.cpp works.
If you look carefully it asks the user for a value and store this value into a "word" (think a value mod 2^64).
Now when you enter your value - 13109612, what happens is the minus sign is taken mod 2^64.

Therefore you end up inputting 2^64 - 13109612, instead of 340282366920938463463374607431768211507 - 13109612 as you intended.

You can fix this by either implementing your own IO class, or as Nigel suggests, input a sign bit separately.

Best,
Titouan

abdelrahaman aly

unread,
Nov 27, 2021, 4:53:13 AM11/27/21
to SPDZ/SCALE-MAMBA Discussion Group
Hi, 
Given that "word" is bounded to 64 bits, I believe the following could be an alternative that could save you the multiplication necessary for encoding the sign: 
Note that  + values are encoded between 0 and 2^63-1, meanwhile - numbers between 2^63 to 2^64-1. 
If you add 2^63 to all values in your file i.e.(v*2^20 + 2^63), you would be switching them, placing + values on the higher interval and - in the lower interval. 
Once the number I loaded using sint.get_private_input_from,  and now living mod p, you could simply subtract the 2^63 you added at the beginning, that way your v will be correctly encoded in SM.

Kr,
A.

Reply all
Reply to author
Forward
0 new messages