Iterate through single precision floating point numbers between [1,2) - c#

I am working on program that requires me to iterate through all single precision floating point (23 fractions bits) numbers in the range of [1,2). I am not quite sure how to go about this. I am writing this program in C#.
If someone could give me some help with this, that would be awesome. Thank you!

You could use the BitConverter static class to convert float value to int and back. Thus you can access its bits.
int one = BitConverter.ToInt32(BitConverter.GetBytes(1f), 0);
int two = BitConverter.ToInt32(BitConverter.GetBytes(2f), 0);
for (int i = one; i < two; i++)
{
float f = BitConverter.ToSingle(BitConverter.GetBytes(i), 0);
// Your stuff
}

Related

Can't get my simple Lorentz factor calculator to work with decimals. What am I missing?

I'm trying to make a calculator that calculates Lorentz factor in c#. But it doesn't seem to work with decimals. I've only done the first part of the calculator:
static void Main(string[] args)
{
int c = 299792458;
Console.Write("speed: ");
string speed = Console.ReadLine();
Console.Write("Gammafaktor: ");
string Gammafaktor = Console.ReadLine();
{
}
int gamma1 = Convert.ToInt32(Gammafaktor);
int speed1 = Convert.ToInt32(speed);
if (gamma1 != 0)
{
Console.WriteLine(1 / (Math.Sqrt(1 - ((speed1 * speed1) / (1)))));
}
}
}
}
If you want to calculate with decimals, then you need to use Double data type instead of an Integer.
An int has a range from -2,147,483,648 to 2,147,483,647 and a double has a range from +-5.0 x 10-324 to +-1.7 x 10308.
You see that a int can't handle decimals.
If the factor of your number would be high, I advice you to use Decimal
Decimals have much higher precision and are usually used within monetary (financial) applications that require a high degree of accuracy.
Reference
Besides lorenz factor uses 1 / sqrt(1 - v*v)
var calc = 1m / Convert.ToDecimal(Math.Sqrt(1 - speed1*speed1));
When you divide by 1 instead of c under the square root, this means that you measure speed in units of c, not in m/s. Consequently, the numerical value of velocity must be a fraction of 1.
However, your variable speed1 is an integer.

c# : do while loop not working as supossed

This program should work for both the condition , atleast i think, but for some values it's not working as supposed.
static void Main(string[] args)
{
double num, temp = 0;
double frac;
int j = 1;
num = 1034.264;
do
{
j = j * 10;
Console.WriteLine(j);
temp = num * j;
Console.WriteLine(temp);
}
while ((temp % 10)!=0);
}
For value 1034.347 , its working fine --
working for 1034.347
but for value 1034.235
not working 1034.235
it is going to infinite
C# - in order to keep up with the Joneses - has a floating point modulus operator %.
It's unlikely that the resultant binary floating point value will have all its trailing digits set to zero when represented as a decimal number, so (temp % 10)!=0) being false is a rarity.
A workaround in your case would be to work in a factor of 1000 of you values, and use an appropriate integral type.
Reference: Is floating point math broken?
Comparing floating points numbers with equal is very dangerous, because floating point operations have an error. E.g. the number is not zero, it's 0.0[..]01 - or: near zero. I suggest comparing with a "bandwith":
abs(nubmer) < 0.000001.

Decimal to exact fraction converter in c#

So I have started a project where I make a quadratic equation solver and I have managed to do so. My next step is to convert the value of X1 and X2 eg.(X+X1)(X+X2) to an exact fraction, if they become a decimal.
So an example is:
12x2 + 44x + 21
gives me,
X1 = -3.10262885097732
X2 = -0.564037815689349
But how would i be able to convert this to an exact fraction?
Thanks for the help!
You can solve this problem using Continued Fractions.
As stated in comments, you can't obtain a fraction (a rational number) that exactly represents an irrational number, but you can get pretty close.
I implemented once, in a pet project, a rational number type. You can find it here. Look into TryFromDouble for an example of how to get the closest rational number (with specified precision) to any given number using Continued Fractions.
An extract of relevant code is the following (I will
Not post the whole type implementation because it is too long, but the code should still be pretty understandable):
public static bool TryFromDouble(double target, double precision, out Rational result)
{
//Continued fraction algorithm: http://en.wikipedia.org/wiki/Continued_fraction
//Implemented recursively. Problem is figuring out when precision is met without unwinding each solution. Haven't figured out how to do that.
//Current implementation computes rational number approximations for increasing algorithm depths until precision criteria is met, maximum depth is reached (fromDoubleMaxIterations)
//or an OverflowException is thrown. Efficiency is probably improvable but this method will not be used in any performance critical code. No use in optimizing it unless there is
//a good reason. Current implementation works reasonably well.
result = zero;
int steps = 0;
while (Math.Abs(target - Rational.ToDouble(result)) > precision)
{
if (steps > fromDoubleMaxIterations)
{
result = zero;
return false;
}
result = getNearestRationalNumber(target, 0, steps++);
}
return true;
}
private static Rational getNearestRationalNumber(double number, int currentStep, int maximumSteps)
{
var integerPart = (BigInteger)number;
double fractionalPart = number - Math.Truncate(number);
while (currentStep < maximumSteps && fractionalPart != 0)
{
return integerPart + new Rational(1, getNearestRationalNumber(1 / fractionalPart, ++currentStep, maximumSteps));
}
return new Rational(integerPart);
}

Precision error on matrix multiplication

Coding a matrix multiplication in my program, I get precision errors (inaccurate results for large matrices).
Here's my code. The current object has data stored in a flattened array, row after row. Other matrix B has data stored in a flattened array, column after column (so I can use pointer arithmetic).
protected double[,] multiply (IMatrix B)
{
int columns = B.columns;
int rows = Rows;
int size = Columns;
double[,] result = new double[rows,columns];
for (int row = 0; row < rows; row++)
{
for (int col = 0; col < columns; col++)
{
unsafe
{
fixed (float* ptrThis = data)
fixed (float* ptrB = B.Data)
{
float* mePtr = ptrThis + row*rows;
float* bPtr = ptrB + col*columns;
double value = 0.0;
for (int i = 0; i < size; i++)
{
value += *(mePtr++) * *(bPtr++);
}
result[row, col] = value;
}
}
}
}
}
Actually, the code is a bit more complicated : I do the multiply thing for several chunks (so instead of having i from 0 to size, I go from localStart to localStop), then sum up the resulting matrices.
My problem : for a big matrix I get precision error :
NUnit.Framework.AssertionException: Error at (0,1)
expected: <6.4209571409444209E+18>
but was: <6.4207619776304906E+18>
Any idea ?
Perhaps all you have to do is use Kahan summation. But you can never expect to get exactly a specific result with floating-point math.
Turns out it was just ... a bug. Ended up that instead of having :
float* mePtr = ptrThis + row*rows;
float* bPtr = ptrB + col*columns;
The correct indexers for my rows were :
float* mePtr = ptrThis + row * size;
float* bPtr = ptrB + col * size;
Sorry for that, not really fancy answer here. But thanks for the help !
I originally stated that you should convert the floats to doubles. However, as you point out that will break your algorithm.
You could try:
value += (double)*(mePtr++) * (double)*(bPtr++);
A problem with your code as it now stands is that the multiplication is being done in float precision then added to a double. Casting to double first will help to some extent.
It might be clearer to use intermediate double variables - but that's up to you.
If this doesn't give you the desire accuracy then you'll need to consider using decimal instead of double. However, this may result in a performance hit so do some benchmarks first.
Hem, it doesn't really solve your problem but in NUnit, you can allow to have a precision error and choose the value of this epsilon
As a starting point, use double everywhere instead of float.
At the very least, you should be using doubles throughout. Floats are very imprecise.
This is a phenomenon called "Matrix Creep" which happens gradually during matrix manipulations if you don't consistently normalize your matrices.

Fractional Counting Via Integers

I receive an integer that represents a dollar amount in fractional denominations. I would like an algorithm that can add those numbers without parsing and converting them into doubles or decimals.
For example, I receive the integer 50155, which means 50 and 15.5/32 dollars. I then receive 10210 which is 10 and 21/32 dollars. So 50 15.5/32 + 10 21/32 = 61 4.5/32, thus:
50155 + 10210 = 61045
Again, I want to avoid this:
int a = 50155;
int b = a / 1000;
float c = a % 1000;
float d = b;
d += c / 320f;
// d = 50.484375
I would much prefer this:
int a = 50155;
int b = 10210;
int c = MyClass.Add(a.b); // c = 61045
...
public int Add(int a, int b)
{
// ?????
}
Thanks in advance for the help!
Well I don't think you need to use floating point...
public static int Add(int a, int b)
{
int firstWhole = a / 1000;
int secondWhole = b / 1000;
int firstFraction = a % 1000;
int secondFraction = b % 1000;
int totalFraction = firstFraction + secondFraction;
int totalWhole = firstWhole + secondWhole + (totalFraction / 320);
return totalWhole * 1000 + (totalFraction % 320);
}
Alternatively, you might want to create a custom struct that can convert to and from your integer format, and overloads the + operator. That would allow you to write more readable code which didn't accidentally lead to other integers being treated as this slightly odd format.
EDIT: If you're forced to stick with a "single integer" format but get to adjust it somewhat you may want to consider using 512 instead of 1000. That way you can use simple mask and shift:
public static int Add(int a, int b)
{
int firstWhole = a >> 9;
int secondWhole = b >> 9;
int firstFraction = a & 0x1ff
int secondFraction = b & 0x1ff;
int totalFraction = firstFraction + secondFraction;
int totalWhole = firstWhole + secondWhole + (totalFraction / 320);
return (totalWhole << 9) + (totalFraction % 320);
}
There's still the messing around with 320, but it's at least somewhat better.
Break the string up in the part that represents whole dollars, and the part that represents fractions of dollars. For the latter, instead of treating it as 10.5 thirty-seconds of a dollar, it's probably easier to treat it as 105 three hundred and twentieths of a dollar (i.e. multiply both by ten to the numerator is always an integer).
From there, doing math is fairly simple (if somewhat tedious to write): add the fractions. If that exceeds a whole dollar, carry a dollar (and subtract 320 from the fraction part). Then add the whole dollars. Subtraction likewise -- though in this case you need to take borrowing into account instead of carrying.
Edit:
This answer suggests that one "stays away" from float arithmetic. Surprisingly, the OP indicated that his float-based logic (not shown for proprietary reasons) was twice as fast as the integer-modulo solution below! Comes to show that FPUs are not that bad after all...
Definitively, stay away from floats (for this particular problem). Integer arithmetic is both more efficient and doesn't introduce rounding error issues.
Something like the following should do the trick
Note: As written, assumes A and B are positive.
int AddMyOddlyEncodedDollars (int A, int B) {
int sum;
sum = A + B
if (sum % 1000 < 320);
return sum
else
return sum + 1000 - 320;
}
Edit: On the efficiency of the modulo operator in C
I depends very much on the compiler... Since the modulo value is known at compile time, I'd expect most modern compilers to go the "multiply [by reciprocal] and shift" approach, and this is fast.
This concern about performance (with this rather contrived format) is a calling for premature optimization, but then again, I've seen software in the financial industry mightily optimized (to put it politely), and justifiably so.
As a point for learning, this representation is called "fixed point". There are a number of implementations that you can look at. I would strongly suggest that you do NOT use int as your top level data type, but instead create a type called Fixed that encapsulates the operations. It will keep your bug count down when you mistakenly add a plain int to a fixed point number without scaling it first, or scale a number and forget to unscale it.
Looks like a strange encoding to me.
Anyway, if the format is in 10-base Nxxx where N is an integer denoting whole dollars and xxx is interpreted as
(xxx / 320)
and you want to add them together, the only thing you need to handle is to do carry when xxx exceeds 320:
int a = ..., b = ...; // dollar amounts
int c = (a + b); // add together
// Calculate carry
int carry = (c % 1000) / 320; // integer division
c += carry * 1000;
c -= carry * 320;
// done
Note: this works because if a and b are encoded correctly, the fractional parts add together to 638 at most and thus there is no "overflow" to the whole dollars part.
BEWARE: This post is wrong, wrong, wrong. I will remove it as soon as I stop feeling a fool for trying it.
Here is my go: You can trade space for time.
Construct a mapping for the first 10 bits to a tuple: count of dollars, count of piecesof32.
Then use bit manipulation on your integer:
ignore bits 11 and above, apply map.
shift the whole number 10 times, add small change dollars from mapping above
you now have the dollar amoung and the piecesof32 amount
add both
move overflow to dollar amount
Next, to convert back to "canonical" notation, you need a reverse lookup map for your piecesof32 and "borrow" dollars to fill up the bits. Unshift the dollars 10 times and add the piecesof32.
EDIT: I should remove this, but I am too ashamed. Of course, it cannot work. I'm so stupid :(
The reason being: shifting by 10 to the right is the same as dividing by 1024 - it's not as if some of the lower bits have a dollar amount and some a piecesof32 amount. Decimal and binary notation just don't split up nicely. Thats why we use hexadecimal notation (grouping of 4 bits). Bummer.
If you insist on working in ints you can't solve your problem without parsing -- after all your data is not integer. I call into evidence the (so far) 3 answers which all parse your ints into their components before performing arithmetic.
An alternative would be to use rational numbers with 2 (integer) components, one for the whole part, and one for the number of 320ths in the fractional part. Then implement the appropriate rational arithmetic. As ever, choose your representations of data carefully and your algorithms become much easier to implement.
I can't say that I think this alternative is particularly better on any axis of comparison but it might satisfy your urge not to parse.

Categories