From a9fcd2cf2bfb42693787e8c4197e5988e155e235 Mon Sep 17 00:00:00 2001 From: Andreas Heinisch Date: Sun, 4 Apr 2021 19:34:47 +0200 Subject: tdf#141201 - Round MOD literals to Integer values (regression from commit I8dbfdf4bb2eceac0b5afbddd3f35e1dcde2db68b "tdf#84435: Mod operator does not deal with decimals as described in help"). Change-Id: I74b231d3814148579a3be0a92b7602fa4387281f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/113571 Tested-by: Jenkins Reviewed-by: Andreas Heinisch --- basic/qa/basic_coverage/test_mod_operator.vb | 25 +++++++++++++++++++++++++ basic/source/comp/exprnode.cxx | 13 +++++++++---- 2 files changed, 34 insertions(+), 4 deletions(-) create mode 100644 basic/qa/basic_coverage/test_mod_operator.vb (limited to 'basic') diff --git a/basic/qa/basic_coverage/test_mod_operator.vb b/basic/qa/basic_coverage/test_mod_operator.vb new file mode 100644 index 000000000000..006d97558052 --- /dev/null +++ b/basic/qa/basic_coverage/test_mod_operator.vb @@ -0,0 +1,25 @@ +' +' This file is part of the LibreOffice project. +' +' This Source Code Form is subject to the terms of the Mozilla Public +' License, v. 2.0. If a copy of the MPL was not distributed with this +' file, You can obtain one at http://mozilla.org/MPL/2.0/. +' + +Function doUnitTest as Integer + + doUnitTest = 0 + + Dim a As Double, b as Double + a = 16.4 + b = 5.9 + + ' tdf#141201 - MOD operands are rounded to Integer values before the operation is performed + if (a MOD b <> 4) Then Exit Function + if (16.4 MOD 5.9 <> 4) Then Exit Function + if (15.9 MOD 6.4 <> 4) Then Exit Function + if (2147483647.4 MOD 4 <> 3) Then Exit Function + + doUnitTest = 1 + +End Function diff --git a/basic/source/comp/exprnode.cxx b/basic/source/comp/exprnode.cxx index 02f8801f1aea..1771da0017f3 100644 --- a/basic/source/comp/exprnode.cxx +++ b/basic/source/comp/exprnode.cxx @@ -27,6 +27,8 @@ #include +#include + SbiExprNode::SbiExprNode( std::unique_ptr l, SbiToken t, std::unique_ptr r ) : pLeft(std::move(l)), pRight(std::move(r)), @@ -294,8 +296,13 @@ void SbiExprNode::FoldConstantsBinaryNode(SbiParser* pParser) { double nl = pLeft->nVal; double nr = pRight->nVal; + // tdf#141201 - round MOD literals to Integer values + if (eTok == MOD) + { + nl = rtl::math::round(nl); + nr = rtl::math::round(nr); + } tools::Long ll = 0, lr = 0; - tools::Long llMod = 0, lrMod = 0; if( ( eTok >= AND && eTok <= IMP ) || eTok == IDIV || eTok == MOD ) { @@ -322,8 +329,6 @@ void SbiExprNode::FoldConstantsBinaryNode(SbiParser* pParser) nr = SbxMINLNG; } ll = static_cast(nl); lr = static_cast(nr); - llMod = static_cast(nl); - lrMod = static_cast(nr); if( bErr ) { pParser->Error( ERRCODE_BASIC_MATH_OVERFLOW ); @@ -388,7 +393,7 @@ void SbiExprNode::FoldConstantsBinaryNode(SbiParser* pParser) { pParser->Error( ERRCODE_BASIC_ZERODIV ); nVal = HUGE_VAL; bError = true; - } else nVal = llMod - lrMod * (llMod/lrMod); + } else nVal = ll - lr * (ll/lr); eType = SbxLONG; break; case AND: nVal = static_cast( ll & lr ); eType = SbxLONG; break; -- cgit