9#ifndef FORTRAN_EVALUATE_INT_POWER_H_
10#define FORTRAN_EVALUATE_INT_POWER_H_
14#include "flang/Evaluate/target.h"
18template <
typename REAL,
typename INT>
19ValueWithRealFlags<REAL> TimesIntPowerOf(
const REAL &factor,
const REAL &base,
21 Rounding rounding = TargetCharacteristics::defaultRounding) {
22 ValueWithRealFlags<REAL> result{factor};
23 if (base.IsNotANumber()) {
24 result.value = REAL::NotANumber();
25 result.flags.set(RealFlag::InvalidArgument);
26 }
else if (power.IsZero()) {
27 if (base.IsZero() || base.IsInfinite()) {
28 result.flags.set(RealFlag::InvalidArgument);
31 bool negativePower{power.IsNegative()};
32 INT absPower{power.ABS().value};
34 int nbits{INT::bits - absPower.LEADZ()};
35 for (
int j{0}; j < nbits; ++j) {
38 squares.Multiply(squares, rounding).AccumulateFlags(result.flags);
40 if (absPower.BTEST(j)) {
42 result.value = result.value.Divide(squares, rounding)
43 .AccumulateFlags(result.flags);
45 result.value = result.value.Multiply(squares, rounding)
46 .AccumulateFlags(result.flags);
54template <
typename REAL,
typename INT>
55ValueWithRealFlags<REAL> IntPower(
const REAL &base,
const INT &power,
56 Rounding rounding = TargetCharacteristics::defaultRounding) {
57 REAL one{REAL::FromInteger(INT{1}).value};
58 return TimesIntPowerOf(one, base, power, rounding);