diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2015-09-10 12:02:17 -0700 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2015-09-10 12:02:17 -0700 |
commit | a17ffca8c1487008ec417d3d75309f541df7268e (patch) | |
tree | 0136b9476a2974f5e4d82a57860fa40384ffdc5e | |
parent | f5465e1220d73e237c51897b7d1211ec53b0dc04 (diff) | |
download | mu-a17ffca8c1487008ec417d3d75309f541df7268e.tar.gz |
2178 - don't die on divide by 0
-rw-r--r-- | 021arithmetic.cc | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/021arithmetic.cc b/021arithmetic.cc index 81cbb544..107f0853 100644 --- a/021arithmetic.cc +++ b/021arithmetic.cc @@ -51,7 +51,7 @@ case SUBTRACT: { } if (!scalar(ingredients.at(0))) { raise << current_recipe_name() << ": 'subtract' requires number ingredients, but got " << current_instruction().ingredients.at(0).original_string << '\n' << end(); - goto finish_instruction; + break; } double result = ingredients.at(0).at(0); for (long long int i = 1; i < SIZE(ingredients); ++i) { @@ -137,7 +137,7 @@ case DIVIDE: { } if (!scalar(ingredients.at(0))) { raise << current_recipe_name() << ": 'divide' requires number ingredients, but got " << current_instruction().ingredients.at(0).original_string << '\n' << end(); - goto finish_instruction; + break; } double result = ingredients.at(0).at(0); for (long long int i = 1; i < SIZE(ingredients); ++i) { @@ -187,10 +187,16 @@ case DIVIDE_WITH_REMAINDER: { } if (!scalar(ingredients.at(0)) || !scalar(ingredients.at(1))) { raise << current_recipe_name() << ": 'divide-with-remainder' requires number ingredients, but got '" << current_instruction().to_string() << "'\n" << end(); - goto finish_instruction; + break; } - long long int quotient = ingredients.at(0).at(0) / ingredients.at(1).at(0); - long long int remainder = static_cast<long long int>(ingredients.at(0).at(0)) % static_cast<long long int>(ingredients.at(1).at(0)); + long long int a = static_cast<long long int>(ingredients.at(0).at(0)); + long long int b = static_cast<long long int>(ingredients.at(1).at(0)); + if (b == 0) { + raise << current_recipe_name() << ": divide by zero in '" << current_instruction().to_string() << "'\n" << end(); + break; + } + long long int quotient = a / b; + long long int remainder = a % b; // very large integers will lose precision products.at(0).push_back(quotient); products.at(1).push_back(remainder); @@ -215,11 +221,24 @@ recipe main [ :(scenario divide_with_decimal_point) recipe main [ - # todo: literal floats? 1:number <- divide 5, 2 ] +mem: storing 2.5 in location 1 +:(scenario divide_by_zero) +recipe main [ + 1:number <- divide 4, 0 +] ++mem: storing inf in location 1 + +:(scenario divide_by_zero_2) +% Hide_warnings = true; +recipe main [ + 1:number <- divide-with-remainder 4, 0 +] +# integer division can't return floating-point infinity ++warn: main: divide by zero in '1:number <- divide-with-remainder 4, 0' + :(code) inline bool scalar(const vector<long long int>& x) { return SIZE(x) == 1; |