From 343f484c382fd1e074db7969bbca4ee01370378f Mon Sep 17 00:00:00 2001 From: Marcel Keller Date: Fri, 4 Jan 2019 17:33:12 +0100 Subject: [PATCH] Variable precision for floating-point outputs. --- Compiler/instructions.py | 5 +++++ Compiler/instructions_base.py | 1 + Compiler/library.py | 3 +++ GC/Processor.h | 1 + GC/Processor.hpp | 7 +++++++ GC/instructions.h | 1 + Processor/Instruction.cpp | 5 +++++ Processor/Instruction.h | 1 + Programs/Source/tutorial.mpc | 4 ++++ 9 files changed, 28 insertions(+) diff --git a/Compiler/instructions.py b/Compiler/instructions.py index 04bd560c..18a07121 100644 --- a/Compiler/instructions.py +++ b/Compiler/instructions.py @@ -952,6 +952,11 @@ class print_float_plain(base.IOInstruction): code = base.opcodes['PRINTFLOATPLAIN'] arg_format = ['c', 'c', 'c', 'c'] +class print_float_prec(base.IOInstruction): + __slots__ = [] + code = base.opcodes['PRINTFLOATPREC'] + arg_format = ['int'] + class print_char(base.IOInstruction): r""" Print a single character to stdout. """ code = base.opcodes['PRINTCHR'] diff --git a/Compiler/instructions_base.py b/Compiler/instructions_base.py index 382fbd5c..dde5c3a6 100644 --- a/Compiler/instructions_base.py +++ b/Compiler/instructions_base.py @@ -163,6 +163,7 @@ opcodes = dict( WRITEFILESHARE = 0xBD, READFILESHARE = 0xBE, CONDPRINTSTR = 0xBF, + PRINTFLOATPREC = 0xE0, GBITDEC = 0x184, GBITCOM = 0x185, # Secure socket diff --git a/Compiler/library.py b/Compiler/library.py index d56c9a73..01577bb5 100644 --- a/Compiler/library.py +++ b/Compiler/library.py @@ -103,6 +103,9 @@ def print_ln_if(cond, s): cond.print_if(s[:4]) s = s[4:] +def print_float_precision(n): + print_float_prec(n) + def runtime_error(msg='', *args): """ Print an error message and abort the runtime. """ print_str('User exception: ') diff --git a/GC/Processor.h b/GC/Processor.h index a05f8682..76d5b234 100644 --- a/GC/Processor.h +++ b/GC/Processor.h @@ -87,6 +87,7 @@ public: void print_chr(int n); void print_str(int n); void print_float(const vector& args); + void print_float_prec(int n); }; template diff --git a/GC/Processor.hpp b/GC/Processor.hpp index 60ba2cb9..20769f08 100644 --- a/GC/Processor.hpp +++ b/GC/Processor.hpp @@ -6,6 +6,7 @@ #include #include +#include using namespace std; #include "GC/Program.h" @@ -224,4 +225,10 @@ void Processor::print_float(const vector& args) T::out << bigint::get_float(C[args[0]], C[args[1]], C[args[2]], C[args[3]]) << flush; } +template +void Processor::print_float_prec(int n) +{ + T::out << setprecision(n); +} + } /* namespace GC */ diff --git a/GC/instructions.h b/GC/instructions.h index b8551e0f..36284dee 100644 --- a/GC/instructions.h +++ b/GC/instructions.h @@ -78,6 +78,7 @@ X(PRINTCHR, PROC.print_chr(IMM)) \ X(PRINTSTR, PROC.print_str(IMM)) \ X(PRINTFLOATPLAIN, PROC.print_float(EXTRA)) \ + X(PRINTFLOATPREC, PROC.print_float_prec(IMM)) \ X(CONDPRINTSTR, if(C0.get()) PROC.print_str(IMM)) \ X(LDINT, I0 = int(IMM)) \ X(ADDINT, I0 = I1 + I2) \ diff --git a/Processor/Instruction.cpp b/Processor/Instruction.cpp index aa1f4469..ea0d1a6d 100644 --- a/Processor/Instruction.cpp +++ b/Processor/Instruction.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include "Tools/callgrind.h" @@ -261,6 +262,7 @@ void BaseInstruction::parse_operands(istream& s, int pos) case START: case STOP: case LISTEN: + case PRINTFLOATPREC: n = get_int(s); break; // instructions with no operand @@ -1503,6 +1505,9 @@ inline void Instruction::execute(Processor& Proc) const Proc.out << bigint::get_float(v, exp, z, s) << flush; } break; + case PRINTFLOATPREC: + Proc.out << setprecision(n); + break; case PRINTSTR: { Proc.out << string((char*)&n,sizeof(n)) << flush; diff --git a/Processor/Instruction.h b/Processor/Instruction.h index 96c68c65..01144782 100644 --- a/Processor/Instruction.h +++ b/Processor/Instruction.h @@ -166,6 +166,7 @@ enum WRITEFILESHARE = 0xBD, READFILESHARE = 0xBE, CONDPRINTSTR = 0xBF, + PRINTFLOATPREC = 0xE0, // GF(2^n) versions diff --git a/Programs/Source/tutorial.mpc b/Programs/Source/tutorial.mpc index 7567e605..b9c84e67 100644 --- a/Programs/Source/tutorial.mpc +++ b/Programs/Source/tutorial.mpc @@ -57,6 +57,10 @@ test(a[99], 99 * 98) sfix.set_precision(16, 32) +# and the output precision in decimal digits + +print_float_precision(4) + # you can do all basic arithmetic with sfix, including division a = sfix(2)