I'm working on a solution to the third exercise of project Euler, and I need to loop over the odd numbers below sqrt(600851475143.0). But I can't subtract 2 from the number every time the loop iterates, it stays the same every time. According to this answer that is due to how numbers are stored and that everything just above and everything under the decimal point is lost. How do I solve this? I need decimal numbers, so I can't use an int (which would not have been big enough anyway).
Since you're looking for odd numbers, and odd numbers are by definition integer, just use an appropriate integer type instead of floating-point maths.
Related
so the problem I have is that there is two integers (a, b) that is in [1, 10^16] interval and I need to do find out how many digits will number a^b have? Those numbers are too big for saving them on single variables, and if I write them on Array it would take a lot of time.
Is there a way to count the number a^b number of digits with some kind of formula or any simpler way then Arrays?
after fixing the one-off error suggested in the comments
number of digits of a^b = floor( b * log(a) ) + 1
karakfa has it right.
The base-k logarithm of a number n, rounded up to the nearest whole number, will give you the number of digits required to represent n in base k.
EDIT: as pointed out in comments, it should not be rounded up, but rounded down and then incremented by one. This accounts for round powers of 10 having an extra digit.
If your number is a^b then take the base-10 logarithm, log a^b and use the laws of logarithms to simplify as b log a. Note that this simplification happens inside the ceiling function so the simplification is valid. Computing log a should not be an issue (it will be between 0 and 16) and b is known. Just make sure to round after multiplying, not before.
Note that limited precision of floating-point numbers may introduce some errors into this method. If the true value of b x log a is different from the nearest floating-point representation of b x log a in such a way that they fall on different sides of an integer, the method fails. You can possibly detect when you are close to this condition and remediate it somehow.
You could use a library that supports arbitrarily large numbers, like GMP .
The core C++ language itself offers no types to work with such large numbers. So either you use a pre-existing library or write one yourself (I suggest the former - don't re-invent the wheel).
I am trying to do some calculations in Fortran that looks like:
large number (order E40) - large number (order E40)
I should get back zero. Most of the time it works, but in a couple of cases I'm getting weird numbers. One answer Fortran gave me was -1E20. Another weird answer I got was 32768, which is 2^15, oddly enough.
Does anyone have any clue as to why this is happening?
It's hard to tell without actual code, but...
This is only to be expected if the numbers are sufficiently similar. While 1e20 is pretty large compared to 1 or 2, it is pretty small compared to 1e40.
In fact, even with double precision, you only have 15-17 digits of precision. Considering that, the values you get are below the accuracy possible with numbers in the range of 1e40.
What you see is numerical noise.
[ Another possibility, of course, is that you are trying to do this in single precision. This is not possible (max. exponent ~38) and anything might happen. ]
The text in quotes gives a bit of background on my program in case it's needed to understand my issue, you might be able to fully understand with the stuff at the end unquoted if you don't feel like reading it.
I'm working on the common project of sorting in C++, and I am
currently doing radix sort. I have it as a function, taking in a
vector of strings, an integer holding the max number of digits, and an
integer with the radix/base of the numbers: (numbers, maxDigits, radix)
Since the program takes in numbers of different base and as a string,
I'm using stoi to convert them to a base 10 integer to make the
process easier to generalize. Here's a quick summary of the algorithm:
create 10 queues to hold values 0 to 9
iterate through each digit (maxDigit times)
iterate through each number in the vector (here it converts to a base 10)
put them into the queue based on the current digit it's looking at
pull the numbers out of the queues from beginning to end back into the vector
As for the problem I'm trying to wrap my head around, I want to change the maxDigit value (with whatever radix the user inputs) to a maxDigit value after it is converted to base 10. In other words, say the user used the code
radixSort(myVector, 8, 2)
to sort a vector of numbers with the max number of digits 8 and a radix of 2. Since I convert the radix of the number to 10, I'm trying to find an algorithm to also change the maxDigits, if that makes sense.
I've tried thinking about this so much, trying to figure out a simple way through trial and error. If I could get some tips or help in the right direction that would be a great help.
If something is in radix 2 and max digits 8, then its largest value is all ones. And 11111111 = 255, which is (2^8 - 1).
The maximum digits in base 10 will be whatever is needed to represent that largest value. Here we see that to be 3. Which is the base 10 logarithm of 255 (2.40654018043), rounded up to 3.
So basically just round up log10 (radix^maxdigits - 1) to the nearest whole number.
I am writing a float printing and formatting library and want to avoid printing trailing zero digits.
For this I would like to accurately determine the last nonzero digit within the first N decimal places after the decimal point. I wonder whether there is a particular efficient way to do this.
This (non-trivial) problem has been fully solved. The idea is to print exactly enough digits so that if you converted the printed digits back to a floating-point number, you would get exactly the number you started with.
The relevant paper is "Printing Floating-Point Numbers Quickly and Accurately", by Robert Burger and R. Kent Dybvig. You can download it here.
You will have to convert the float to a string and then trim the trailing zeros.
I don't think this is very efficient, but i feel there is probably no simplier algorithm
std::cout.precision(n);
//where n is the digits you want to display after the decimal.
If there is a zero present before the precision limit but after decimal,
it will be avoided automatically.
eg. std::cout.precision(5);
then my conidition is evaluated to be 5.55000
only 5.55 will be printed
The obvious solution is to put all digits in a char[N] and check the last digit before printing. But I bet you have thought about that yourself.
The only other solution I can think of, is that the decimal part of 2^(-n) has n non-zero digits.
So if the last non-zero in the binary representation is 2^(-n), there will be exactly n non-zero digits in the decimal expansion. Therefor looking at the binary representation will tell you something about the decimal representation.
However, this is only a partial solution, as rounding could introduce additional trailing zeros.
So, for a very silly project in C++, we are making our own long integer class, called VLI (Very Long Int). The way it works (they backboned it, blame them for stupidity) is this:
User inputs up to 50 digits, which are input as string.
String is stored in pre-made Sequence class, which stores the string in an array, in reverse order.
That means, when "1234" is input, it gets stored as [4|3|2|1].
So, my question is this: How can I go about doing division using only these arrays of chars?
If the input answer is over 32 digits, I can't use ints to check for stuff, and they basically saying using long ints here is cheating.
Any input is welcome, and I can give more clarification if need be, thanks everyone.
Implement the long division algorithm you learned in grade school.
Start by implementing subtraction. Create a function which can string-subtract any number from the input. Then you should be able to detect whether the result is negative. Modify this function to allow the number to be string-shifted before you subtract…
Get your school math book out, you did manual division some years ago in school I suppose. It is exactly the same principle :)
Potatoswatter is correct. I wrote a Pascal program in the past that worked on arbitrary length numbers as strings, and it could calculate the square root as well.
Here is a reminder of technique for long division: Long Division to Decimal Places