Skip to content
This repository has been archived by the owner on May 18, 2019. It is now read-only.

Commit

Permalink
[NF] Make Real range generation more robust.
Browse files Browse the repository at this point in the history
- Generate Real ranges using start+step*i, instead of relying on the
  code generation that uses repeated addition which causes unnecessary
  inaccuracies.

Belonging to [master]:
  - #2909
  • Loading branch information
perost authored and OpenModelica-Hudson committed Jan 30, 2019
1 parent 0f5c4be commit 2f863d0
Showing 1 changed file with 28 additions and 2 deletions.
30 changes: 28 additions & 2 deletions Compiler/NFFrontEnd/NFCeval.mo
Expand Up @@ -686,7 +686,7 @@ algorithm

case (Expression.REAL(), Expression.REAL(), Expression.REAL())
algorithm
expl := list(Expression.REAL(r) for r in start.value:step.value:stop.value);
expl := evalRangeReal(start.value, step.value, stop.value);
then
(Type.REAL(), expl);

Expand All @@ -706,7 +706,7 @@ algorithm

case (Expression.REAL(), Expression.REAL())
algorithm
expl := list(Expression.REAL(r) for r in start.value:stop.value);
expl := evalRangeReal(start.value, 1.0, stop.value);
then
(Type.REAL(), expl);

Expand Down Expand Up @@ -734,6 +734,32 @@ algorithm
expl, literal = true);
end evalRange;

function evalRangeReal
input Real start;
input Real step;
input Real stop;
output list<Expression> result;
protected
Integer steps;
algorithm
steps := Util.realRangeSize(start, step, stop);

// Real ranges are tricky, make sure that start and stop are reproduced
// exactly if they are part of the range.
if steps == 0 then
result := {};
return;
elseif steps == 1 then
result := {Expression.REAL(start)};
else
result := {Expression.REAL(stop)};
for i in steps-1:-1:1 loop
result := Expression.REAL(start + i * step) :: result;
end for;
result := Expression.REAL(start) :: result;
end if;
end evalRangeReal;

function printFailedEvalError
input String name;
input Expression exp;
Expand Down

0 comments on commit 2f863d0

Please sign in to comment.