@@ -211,13 +211,24 @@ struct PythonIntrinsicProcedures {
211
211
if (ASRUtils::is_integer (*type)) {
212
212
int64_t a = ASR::down_cast<ASR::IntegerConstant_t>(arg1)->m_n ;
213
213
int64_t b = ASR::down_cast<ASR::IntegerConstant_t>(arg2)->m_n ;
214
+ if (b == 0 ) { // Zero Division
215
+ throw SemanticError (" Integer division or modulo by zero" ,loc);
216
+ }
217
+
218
+ // Refer the following link to understand how modulo in C++ is modified to behave like Python.
219
+ // https://stackoverflow.com/questions/1907565/c-and-python-different-behaviour-of-the-modulo-operation
214
220
return ASR::down_cast<ASR::expr_t >(
215
- ASR::make_IntegerConstant_t (al, loc, a %b, type));
221
+ ASR::make_IntegerConstant_t (al, loc, ((a%b)+b) %b, type));
216
222
} else if (ASRUtils::is_real (*type)) {
217
223
double a = ASR::down_cast<ASR::RealConstant_t>(arg1)->m_r ;
218
224
double b = ASR::down_cast<ASR::RealConstant_t>(arg2)->m_r ;
225
+ if (b == 0 ) { // Zero Division
226
+ throw SemanticError (" Float division or modulo by zero" , loc);
227
+ }
228
+
229
+ // https://stackoverflow.com/questions/1907565/c-and-python-different-behaviour-of-the-modulo-operation
219
230
return ASR::down_cast<ASR::expr_t >(
220
- ASR::make_RealConstant_t (al, loc, std::fmod (a , b), type));
231
+ ASR::make_RealConstant_t (al, loc, std::fmod (std::fmod (a, b) + b , b), type));
221
232
} else {
222
233
throw SemanticError (" _mod() must have both integer or both real arguments." , loc);
223
234
}
0 commit comments