4 ms·
Oh good, that will be fun. Here's C++ code #include <iostream> #include <cstdint> int64_t scaleFV(int64_t P, int64_t R, int64_t C, int64_t Y)
by SideQuark 4y ago
Oh good, that will be fun.
Here's C++ code
#include <iostream>
#include <cstdint>
int64_t scaleFV(int64_t P, int64_t R, int64_t C, int64_t Y)
{
int64_t SP = 10000; // temporary principal scale factor, 4 decimals
if (P > SP * 1000) SP *= 10; // extend accuracy for larger amounts
int64_t SR = 1000; // annual rate scale factor, 3 decimals (pre-applied to R)
int64_t N = C * Y; // total number of compounding periods
int64_t D = C * 100 * SR; // period rate divisor
P = P * SP; // scale the principal (int64_t)
while (N > 0)
{
std::cout << P * R << std::endl; // watch the errors fly!
P = P + ((P * R) / D); // compound principal with period interest
N--; // count the period
}
return (P + SP / 2) / SP; // unscale result, round back to nearest penny
}
int main()
{
std::cout << scaleFV(10000000000L, 8000, 12, 30) << " = 11605682736 != 109357296578\n" << std::endl;
}
I added a print in your loop to show you the overflow. Good luck. To help you, P * R for this calculation gets about 4x as big as an int 64 can hold.
Another way to see it is your answer 109357296578, times your scaling 100000, requires P to hold > 53 bits. But your rate of 8000 is almost 13 bits. So P * R cannot fit in a 64 (well 63 for signed) int.
If you cannot fix it, care to explain how your code works only with int64 as you claim here and in other threads on this page? Maybe then you can address the errors I listed above where your routine failed?
- jqpabc123 4y agoIf you cannot fix it, care to explain how your code works only with int64 as you claim here and in other threads on this page? Yes, your code pukes all over itself. And mine doesn't. Why? For more than 2 decades now, Intel processors have included SSE "extensions" with a whole bank of 128 bit registers (XMM0 thru XMM15) with specialized math instructions for integer and floating point. https://en.wikipedia.org/wiki/Streaming_SIMD_Extensions https://en.wikipedia.org/wiki/Streaming_SIMD_Extensions The compiler I use emits SSE opcodes by default for operations on 64 bit integers when building 64 bit executables. In other words, 128 bit processor registers are being used for the calculations. Overflow occurs when the final resultant is too large for int64. So there you have it.
- SideQuark 4y ago>For more than 2 decades now, Intel processors have included SSE "extensions" with a whole bank of 128 bit registers (XMM0 thru XMM15) with specialized math instructions for integer and floating point. That's interesting, since Intel did not add 128 bit wide integer math in SSE. Those 128 bit registers were SIMD, meaning multiple data, meaning at most 64 bit integers. Later extensions (not two decades back) added larger registers. I wrote the article for Intel for the release for AVX in 2011 [2], where Intel expanded the registers to 256 bit (still no 128 bit integer math). But there has certainly not been 128 bit wide integer operations for two decades. There has been 128 bit registers split into at most 64 bit sized components, the M in SIMD. I also wrote decompilers for Intel binaries, and just looked through that code, and again, no 128 bit integers. Are you confusing 128 (or 256 or 512) bit wide registers that are split into components as actually 128 or 256 or 512 bit integer registers? Are you making stuff up? Intel intrinsics denote register size and SIMD size. For example, _mm256_add_epi16 means use 256 bit registers, and add packed integers of 16 bit size. There are no _epi128 intrinsics, only size 8,16,32,64 [1]. Another interesting place to look for these 128 bit integer instructions is [3]. Lots of IntN for N = 8,16,32,64, none for N=128. Here's [4] the Intel Software Development Manual from April 2022.... Also not seeing them. Section 4.6.2 lists supported data types - not a single 128 bit integer on that page. I don't see them in the AVX and other extension sections either. So I'm super interested in your compiler and language that automatically emits 128 bit wide integer SIMD instructions for Intel, since they are not in the opcode or intrinsic lists. Please name the language and compiler, and even post some working code to demonstrate this auto extension to 128 bit math. And, if you're using 128 bit registers, why would you pick 64 bit math, which fails for all the cases above? You still have not addressed that any size register fails on the examples I posted above, including your auto-extending non-portable compiler tricks. For example, $100000,8000,365,100 fails even on 128 bit, 256 bit, even infinite bit length registers. Because your algorithm itself is bad. So, care to post your compiler, language, and code? Also, why did you keep telling us it was 64 bit when it wasn't? [1] https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html https://www.intel.com/content/www/us/en/docs/intrinsics-guid... [2] https://hpc.llnl.gov/sites/default/files/intelAVXintro.pdf https://hpc.llnl.gov/sites/default/files/intelAVXintro.pdf [3] https://www.felixcloutier.com/x86/index.html https://www.felixcloutier.com/x86/index.html [4] https://www.intel.com/content/www/us/en/developer/articles/technical/intel-sdm.html https://www.intel.com/content/www/us/en/developer/articles/t...