简体   繁体   中英

Normalization of float point when checking if the number is “harmonic divisor number (Ore number)”

My function isOre is checking if the number is "harmonic divisor number (Ore number)" or not ( https://en.wikipedia.org/wiki/Harmonic_divisor_number#CITEREFCohenSorli2010 ). I can not rightfully compare if the "result variable" is integer number because the part of it is inside exponent. ( https://www.h-schmidt.net/FloatConverter/IEEE754.html ).

My question is: 1. How can I solve it? 2. Are there alternative solutions?

#include <iostream>
using namespace std;

bool isOre(unsigned int n){
double numbersSum = 0;
int number = 0;
for (int i = 1; i <= n; ++i){
    if (n % i == 0){
        numbersSum += (double)1 / i ;
        //cout << "numbersSum " << numbersSum << endl;
        ++number;
        //cout << "number " << number << endl;

    }
}

double result = number / numbersSum;
int result1 = result;


cout << "       " << result << "        " << result1 << "       ";
if (result == result1) return true;
else return false;
}

int main() { 
//Test sequence of Ore numbers from https://oeis.org/A001599
int array[34] = {1, 6, 28, 140, 270, 496, 672, 1638, 2970, 6200, 8128,
8190, 18600, 18620, 27846, 30240, 32760, 55860, 105664, 117800, 167400,
173600, 237510, 242060, 332640, 360360, 539400, 695520, 726180, 753480, 950976,
1089270, 1421280, 1539720};

cout << "array[i]" << " " << "double" << "  " << "toInt" << "   " << "Result" << endl;

for (int i = 0; i < 34; ++i){
cout << array[i];
cout << isOre(array[i]) << endl;
}

return 0;
}

In main I have my testcase sequence that must pass.

My Output:

array[i] double toInt Result

1 1 1 1

6 2 2 1

28 3 3 1

140 5 5 1

270 6 6 1

496 5 5 1

672 8 8 0

1638 9 9 0

2970 11 11 0

6200 10 10 1

8128 7 7 1

8190 15 15 0

18600 15 15 0

18620 14 14 0

27846 17 17 0

30240 24 23 0

32760 24 24 0

55860 21 21 0

105664 13 13 0

117800 19 19 0

167400 27 27 0

173600 25 25 0

237510 29 29 0

242060 26 26 0

332640 44 43 0

360360 44 43 0

539400 29 29 1

695520 46 46 0

726180 39 39 0

753480 46 45 0

950976 27 27 0

1089270 42 42 0

1421280 47 46 0

1539720 47 46 0

PS It is not relevant but I will be very thankful if somebody can point out why do I have shift in my output after line that starts with 672.

Links to the materials corresponding the problem.

http://planetmath.org/OreNumber ;

http://steve.hollasch.net/cgindex/coding/ieeefloat.html

http://www.cs.yale.edu/homes/aspnes/pinewiki/C(2f)FloatingPoint.html

https://en.wikipedia.org/wiki/Single-precision_floating-point_format

https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html

As the page you reference notes, the harmonic mean of the divisors of n can be expressed as n •σ 0 ( n ) / σ 1 ( n ), where σ 0 ( n ) is the number of divisors and σ 1 ( n ) is the sum of the divisors. So simply calculate the numerator and the denominator with integer arithmetic and then test whether the remainder of the division would be zero.

Note that the arithmetic will break down for large numbers, so your program must test for this and either stop when it cannot continue or must use alternate arithmetic methods to support large numbers. This is true of either integer or floating-point arithmetic. However, if you are iterating through candidates one by one and using 64-bit integer arithmetic, you will not reach the point where overflow is a problem.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM