How to convert powers of 2 number to multiples of 10 number? - fixed-point

I would like to create a function which converts powers of 2 to multiples of 10.
can anybody help in providing algorithm such that function should use only integers .. Should not use ang float variable.
FUN_Convert(100,524247,1024) /*100->10^2,524247->511.96*1024, 1024 -> 2^10*/
{
int a;
/*Do calculation*/
return a; /*calculated value 51195*/
}

Related

How to round off ten random numbers in array?

Trying to generate ten numbers which are random and without decimal point.
my #randoms = map { rand } (1..10)
This code returns ten random numbers yet with decimal like
0.218220758325518.
I want round off these numbers.
Need a help. Thanks.
rand can take a parameter that specifies the supremum of the generated numbers. Just call int to truncate it:
my #randoms = map int rand 20, 1 .. 10;
It generates numbers in the range 0 .. 19.

Is this a correct way to store dates?

I found this example of storing dates in the book Algorithms 4th edition, using only a single integer. I'm not sure if it is correct.
This is the class definition for a Date.
public class Date
{
private final int value;
public Date(int m, int d, int y)
{ value = y*512 + m*32 + d; }
public int month()
{ return (value / 32) % 16; }
public int day()
{ return value % 32; }
public int year()
{ return value / 512; }
public String toString()
{ return month() + "/" + day()
}
Where do the numbers 512 and 32 come from, and why do we modulo by 16 when calculating the month.
Yes, if your integer has 32 bits, then you can store in it all valid dates from 01-01-0001 up to (more or less) 01-01-8388608, where 8388608 is a year.
Also, the order of the integer values is the same as the natural order of dates.
But how is it done?
First observation is that all possible numbers of days in month fit into the interval [0, 31] (note that 0 will never be used).
Thus, you can store that using just five bits.
Similarly, all possible months fit into the interval [0, 15], so now you only need 4 bits.
Whole date is saved like this:
...011111100001 <---------- year
||||||||||||1100 <------ month
||||||||||||||||10011 <- day
------------------------
011111100001110010011
If you want to get the value of the year, you have to get rid of the initial 9 bits. You can delete one bit by simply dividing the value by 2. To get rid of the 9 bits, you have to divide 9 times by 2, or - in one step - by 2^9 = 512.
In the above example, when you divide 011111100001110010011 by 2^9:
011111100001110010011
1000000000 = 2^9
---------------------
011111100001
you get 011111100001 (or 2017 in decimal).
In short:
division by 2^n == deleting last n bits of a number, shifting everything to the right.
dividion modulo 2^n == looking only at the last n bits.

How to use a fixed point sin function in Vivado HLS

I am calculating the intersection point of two lines given in the polar coordinate system:
typedef ap_fixed<16,3,AP_RND> t_lines_angle;
typedef ap_fixed<16,14,AP_RND> t_lines_rho;
bool get_intersection(
hls::Polar_< t_lines_angle, t_lines_rho>* lineOne,
hls::Polar_< t_lines_angle, t_lines_rho>* lineTwo,
Point* point)
{
float angleL1 = lineOne->angle.to_float();
float angleL2 = lineTwo->angle.to_float();
t_lines_angle rhoL1 = lineOne->rho.to_float();
t_lines_angle rhoL2 = lineTwo->rho.to_float();
t_lines_angle ct1=cosf(angleL1);
t_lines_angle st1=sinf(angleL1);
t_lines_angle ct2=cosf(angleL2);
t_lines_angle st2=sinf(angleL2);
t_lines_angle d=ct1*st2-st1*ct2;
// we make sure that the lines intersect
// which means that parallel lines are not possible
point->X = (int)((st2*rhoL1-st1*rhoL2)/d);
point->Y = (int)((-ct2*rhoL1+ct1*rhoL2)/d);
return true;
}
After synthesis for our FPGA I saw that the 4 implementations of the float sine (and cos) take 4800 LUTs per implementation, which sums up to 19000 LUTs for these 4 functions. I want to reduce the LUT count by using a fixed point sine. I already found a implementation of CORDIC but I am not sure how to use it. The input of the function is an integer but i have a ap_fixed datatype. How can I map this ap_fixed to integer? and how can I map my 3.13 fixed point to the required 2.14 fixed point?
With the help of one of my colleagues I figured out a quite easy solution that does not require any hand written implementations or manipulation of the fixed point data:
use #include "hls_math.h" and the hls::sinf() and hls::cosf() functions.
It is important to say that the input of the functions should be ap_fixed<32, I> where I <= 32. The output of the functions can be assigned to different types e.g., ap_fixed<16, I>
Example:
void CalculateSomeTrig(ap_fixed<16,5>* angle, ap_fixed<16,5>* output)
{
ap_fixed<32,5> functionInput = *angle;
*output = hls::sinf(functionInput);
}
LUT consumption:
In my case the consumption of LUT was reduced to 400 LUTs for each implementation of the function.
You can use bit-slicing to get the fraction and the integer parts of the ap_fixed variable, and then manipulate them to get the new ap_fixed. Perhaps something like:
constexpr int max(int a, int b) { return a > b ? a : b; }
template <int W2, int I2, int W1, int I1>
ap_fixed<W2, I2> convert(ap_fixed<W1, I1> f)
{
// Read fraction part as integer:
ap_fixed<max(W2, W1) + 1, max(I2, I1) + 1> result = f(W1 - I1 - 1, 0);
// Shift by the original number of bits in the fraction part
result >>= W1 - I1;
// Add the integer part
result += f(W1 - 1, W1 - I1);
return result;
}
I haven't tested this code well, so take it with a grain of salt.

Double numbers and bitxor [duplicate]

This question already has answers here:
How to use Bitxor for Double Numbers?
(2 answers)
Closed 9 years ago.
I have two matrices a = [120.23, 255.23669877,...] and b = [125.000083, 800.0101010,...] with double numbers in [0, 999]. I want to use bitxor for a and b. I can not use bitxor with round like this:
result = bitxor(round(a(1,j),round(b(1,j))
Because the decimal parts 0.23 and 0.000083 ,... are very important to me. I thought maybe I could do a = a*10^k and b = b*10^k and use bitxor and after that result/10^k (because I want my result's range to also be [0, 999]. But I do not know the maximum length of the number after the decimal point. Does k = 16 support the max range of double numbers in Matlab? Does bitxor support two 19-digit numbers? Is there a better solution?
This is not really an answer, but a very long comment with embedded code. I don't have a current matlab installation, and in any case don't know enough to answer the question in that context. Instead, I've written a Java program that I think may do what you are asking for. It uses two Java classes, BigInteger and BigDecimal. BigInteger is an extended integer format. BigDecimal is the combination of a BigInteger and a decimal scale.
Conversion from double to BigDecimal is exact. Conversion in the opposite direction may require rounding.
The function xor in my program converts each of its operands to BigDecimal. It finds a number of decimal digits to move the decimal point by to make both operands integers. After scaling, it converts to BigInteger, does the actual xor, and converts back to BigDecimal undoing the scaling.
The main point of this is for you to look at the results, and see whether they are what you want, and would be useful to you if you could do the same thing in Matlab. Explaining any ways in which the results are not what you want may help clarify your requirements for the Matlab experts.
Here is some test output. The top and bottom rows of each block are in decimal. The middle row is the scaled integer versions of the inputs, in hex.
Testing operands 1.100000000000000088817841970012523233890533447265625, 2
2f0a689f1b94a78f11d31b7ab806d40b1014d3f6d59 xor 558749db77f70029c77506823d22bd0000000000000 = 7a8d21446c63a7a6d6a61df88524690b1014d3f6d59
1.1 xor 2.0 = 2.8657425494106605
Testing operands 100, 200.0004999999999881765688769519329071044921875
2cd76fe086b93ce2f768a00b22a00000000000 xor 59aeee72a26b59f6380fcf078b92c4478e8a13 = 7579819224d26514cf676f0ca932c4478e8a13
100.0 xor 200.0005 = 261.9771865509636
Testing operands 120.3250000000000028421709430404007434844970703125, 120.75
d2c39898113a28d484dd867220659fbb45005915 xor d3822c338b76bab08df9fee485d1b00000000000 = 141b4ab9a4c926409247896a5b42fbb45005915
120.325 xor 120.75 = 0.7174277813579485
Testing operands 120.2300000000000039790393202565610408782958984375, 120.0000830000000036079654819332063198089599609375
d298ff20fbed5fd091d87e56002df79fc7007cb7 xor d231e5f39e1db18654cb8c43d579692616a16a1f = a91ad365f0ee56c513f215d5549eb9d1a116a8
120.23 xor 120.000083 = 0.37711627930683345
Here is the Java program:
import java.math.BigDecimal;
import java.math.BigInteger;
public class Test {
public static double xor(double a, double b) {
BigDecimal ad = new BigDecimal(a);
BigDecimal bd = new BigDecimal(b);
/*
* Shifting the decimal point right by scale will make both operands
* integers.
*/
int scale = Math.max(ad.scale(), bd.scale());
/*
* Scale both operands by, in effect, multiplying by the same power of 10.
*/
BigDecimal aScaled = ad.movePointRight(scale);
BigDecimal bScaled = bd.movePointRight(scale);
/*
* Convert the operands to integers, treating any rounding as an error.
*/
BigInteger aInt = aScaled.toBigIntegerExact();
BigInteger bInt = bScaled.toBigIntegerExact();
BigInteger resultInt = aInt.xor(bInt);
System.out.println(aInt.toString(16) + " xor " + bInt.toString(16) + " = "
+ resultInt.toString(16));
/*
* Undo the decimal point shift, in effect dividing by the same power of 10
* as was used to scale to integers.
*/
BigDecimal result = new BigDecimal(resultInt, scale);
return result.doubleValue();
}
public static void test(double a, double b) {
System.out.println("Testing operands " + new BigDecimal(a) + ", " + new BigDecimal(b));
double result = xor(a, b);
System.out.println(a + " xor " + b + " = " + result);
System.out.println();
}
public static void main(String arg[])
{
test(1.1, 2.0);
test(100, 200.0005);
test(120.325, 120.75);
test(120.23, 120.000083);
}
}
"But I do not know the max length of number after point ..."
In double precision floating-point you have 15–17 significant decimal digits. If you give bitxor double inputs these must be less than intmax('uint64'): 1.844674407370955e+19. The largest double, realmax (= 1.797693134862316e+308), is much bigger than this, so you can't represent everything in the the way you're using. For example, this means that your value of 800.0101010*10^17 won't work.
If your range is [0, 999], one option is to solve for the largest fractional exponent k and use that: log(double(intmax('uint64'))/999)/log(10) (= 16.266354234268810).

binary to decimal in objective-c

I want to convert the decimal number 27 into binary such a way that , first the digit 2 is converted and its binary value is placed in an array and then the digit 7 is converted and its binary number is placed in that array. what should I do?
thanks in advance
That's called binary-coded decimal. It's easiest to work right-to-left. Take the value modulo 10 (% operator in C/C++/ObjC) and put it in the array. Then integer-divide the value by 10 (/ operator in C/C++/ObjC). Continue until your value is zero. Then reverse the array if you need most-significant digit first.
If I understand your question correctly, you want to go from 27 to an array that looks like {0010, 0111}.
If you understand how base systems work (specifically the decimal system), this should be simple.
First, you find the remainder of your number when divided by 10. Your number 27 in this case would result with 7.
Then you integer divide your number by 10 and store it back in that variable. Your number 27 would result in 2.
How many times do you do this?
You do this until you have no more digits.
How many digits can you have?
Well, if you think about the number 100, it has 3 digits because the number needs to remember that one 10^2 exists in the number. On the other hand, 99 does not.
The answer to the previous question is 1 + floor of Log base 10 of the input number.
Log of 100 is 2, plus 1 is 3, which equals number of digits.
Log of 99 is a little less than 2, but flooring it is 1, plus 1 is 2.
In java it is like this:
int input = 27;
int number = 0;
int numDigits = Math.floor(Log(10, input)) + 1;
int[] digitArray = new int [numDigits];
for (int i = 0; i < numDigits; i++) {
number = input % 10;
digitArray[numDigits - i - 1] = number;
input = input / 10;
}
return digitArray;
Java doesn't have a Log function that is portable for any base (it has it for base e), but it is trivial to make a function for it.
double Log( double base, double value ) {
return Math.log(value)/Math.log(base);
}
Good luck.