Last active
June 25, 2021 08:28
-
-
Save conqp/30f775e4ba8a1ee5de524a5de4671b02 to your computer and use it in GitHub Desktop.
float sum precision
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <algorithm> | |
using std::for_each; | |
using std::reverse; | |
#include <cmath> | |
using std::modf; | |
#include <iomanip> | |
using std::left; | |
using std::setprecision; | |
using std::setw; | |
#include <iostream> | |
using std::cout; | |
#include <numeric> | |
using std::accumulate; | |
#include <vector> | |
using std::begin; | |
using std::end; | |
using std::vector; | |
float sumNaive(vector<float> const & floats) | |
{ | |
return accumulate(begin(floats), end(floats), 0.0f); | |
} | |
double sumDouble(vector<float> const & floats) | |
{ | |
double result = 0; | |
for (auto f : floats) | |
result += f; | |
return result; | |
} | |
float sumNormalized(vector<float> const & floats) | |
{ | |
int integerSum = 0; | |
float floatSum = 0.0f; | |
for_each(begin(floats), end(floats), [&integerSum, &floatSum] (float num) { | |
float integer; | |
floatSum += modf(num, &integer); | |
integerSum += static_cast<int>(integer); | |
}); | |
return integerSum + floatSum; | |
} | |
float sumStrictlyNormalized(vector<float> const & floats) | |
{ | |
int integerSum = 0; | |
float floatSum = 0.0f; | |
for_each(begin(floats), end(floats), [&integerSum, &floatSum] (float num) { | |
float integer; | |
if (floatSum > 1) { | |
floatSum = modf(floatSum, &integer); | |
integerSum += static_cast<int>(integer); | |
} | |
floatSum += modf(num, &integer); | |
integerSum += static_cast<int>(integer); | |
}); | |
return integerSum + floatSum; | |
} | |
float getRandomFloat() | |
{ | |
return static_cast<float>(rand()) / static_cast<float>(RAND_MAX); | |
} | |
vector<float> getRandomFloats(unsigned int amount) | |
{ | |
vector<float> result; | |
for (unsigned int i = 0; i < amount; ++i) | |
result.push_back(getRandomFloat()); | |
return result; | |
} | |
int main() | |
{ | |
auto floats = getRandomFloats(10'000'000); | |
cout << setprecision(10) << left; | |
cout << "### Unsorted ###\n"; | |
cout << setw(21) << "Double: " << sumDouble(floats) << "\n"; | |
cout << setw(21) << "Naive: " << sumNaive(floats) << "\n"; | |
cout << setw(21) << "Normalized: " << sumNormalized(floats) << "\n"; | |
cout << setw(21) << "Strictly normalized: " << sumStrictlyNormalized(floats) << "\n"; | |
sort(begin(floats), end(floats)); | |
cout << "### Sorted ###\n"; | |
cout << setw(21) << "Double: " << sumDouble(floats) << "\n"; | |
cout << setw(21) << "Naive: " << sumNaive(floats) << "\n"; | |
cout << setw(21) << "Normalized: " << sumNormalized(floats) << "\n"; | |
cout << setw(21) << "Strictly normalized: " << sumStrictlyNormalized(floats) << "\n"; | |
reverse(begin(floats), end(floats)); | |
cout << "### Revese sorted ###\n"; | |
cout << setw(21) << "Double: " << sumDouble(floats) << "\n"; | |
cout << setw(21) << "Naive: " << sumNaive(floats) << "\n"; | |
cout << setw(21) << "Normalized: " << sumNormalized(floats) << "\n"; | |
cout << setw(21) << "Strictly normalized: " << sumStrictlyNormalized(floats) << "\n"; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment