Is it possible convert a double variable to a float (single in Matlab) with fixed floating point?
For example
x = 10.023213032130123021302130210331232132103312321
to
x = 10.0231
Thank you !
First convert to single:
X = single(Y)
And than apply round() to get fixed format:
X = round(10^N*X) / 10^N;
to get N digits behind the decimal point
Related
I'm in the process of implementing Three Fish block cipher using MATLAB. At first, I implemented the algorithm on uint8 numbers to validate my code. Every thing was OK and the decryption was successful. But when I replaced the numbers to uint64 the plain text did not retrieved correctly.
I traced the rounds results again and over again to find the reason, but I couldn't find it so far. There is difference in the first four digits between encryption and decryption, that is, along the rounds x encrypted as 9824265115183455531, but it decrypts as 9824265115183455488.
I think the reason behind this difference is in the functions AddMod64 and SubMod64 to find arithmetic modulo 2 to the power 64. but really I could not fix it so far.
I know that
double(2^64) = 18446744073709552000
and
uint64(2^64) = 18446744073709551615 % z = ( x + y ) % 2^64
function z = AddMod64(x , y)
m = uint64(2^64);
z = double(mod(mod(double(x),m)+mod(double(y),m),m));
end
% z = (x - y ) % 2^64
function z = SubMod64(x , y)
m = uint64(2^64);
z = double(mod(mod(double(x),m) - mod(double(y),m),m));
end
double(2^64) is already the wrong result, the double type can hold only up to 2^52-1 as an integer without rounding.
Also, when you do uint64(2^64), the power is computed using double, giving the wrong result, which you then cast to uint64. And because the maximum value that a uint64 van hold is 2^64-1, that whole operation is wrong.
Use maxint instead:
m = maxint('uint64');
To do modulo addition in MATLAB is rather tricky, because MATLAB does saturated arithmetic with integers. You need to test for overflow before doing the computation.
if x > m - y
x = y - (m - x + 1);
else
x = x + y
end
A floating point is usually given in decimal notation, e.g. 1.25. However for binary the same value could be 1.01.
It is possible to use such binary notation to specify floating point values in MATLAB?
As #Ander Biguri said that is not floating point (IEEE-754 double see here).
However, if you want to represent binary the way you suggest in your question you could do something the example below. In my example you have to specify how many bits you want to represent the binary integer & fractional portions and it outputs as a char array:
num2Convert = 1.25;
numInt = 5; %Number of bits for interger portion
numFrac = 5; %Number of bits for fraction portion
dInt = num2cell(fix(rem(num2Convert*pow2(-numInt+1:0),2)));
% More simply you could just do dec2bin(fix(num2convert)); for the int portion...
% but I wanted to be consistent with the fractional portion
dFrac = num2cell(fix(rem( rem(num2Convert,1)*pow2(1:numFrac),2)));
binString = [sprintf('%d',dInt{:}),'.',sprintf('%d',dFrac{:})]
binString =
00001.01000
Now if you want to see the binary representation of the underlying double precision float you could do this:
binString = dec2bin(typecast(num2Convert,'uint64'),64)
binString =
0011111111110100000000000000000000000000000000000000000000000000
e.g. x = 12.354
I want to get 354 from x. For this I tried this equation,
y = x - floor(x)
But this generates 0.354 which is not my requirement.
So, how can I do it?
The generic idea as pointed out by #JoachimPileborg looks like this in MATLAB:
x = 12.354;
str = num2str(x);
idx = find(str=='.');
substr = str(idx+1:end);
y = str2num(substr);
A generic solution that should work with all programming languages, is to convert the number to a string, then take the sub-string from after the decimal point (or comma) and convert it to an integer.
An alternative (possibly faster) to m.s. 's answer. Notice the 'shift' due to this approach effectively removing the zeroes to the right of the decimal point.
yfoo = 34.00267400;
yfoo = yfoo- floor(yfoo); % .00267400;
% internal rep of number ignores trailing zeros.
yrab = str2num(strrep(num2str(yfoo),'.','')); %2674
So im using MATLAB to calculate the coefficient of an equation and it keeps displaying fractions as the constants instead of decimal form like xxe-x
My code is below
bt = 0.03175;
bpzt = 0.0078;
ht = 0.003;
w = 50; % frequency in Hz
pnic = 8908; % density of nickel
Enic = 200e9; % Young's modulus of nic
L = 0.3048; % Length of canitlever beam in m
syms hn
inertia = (1/12)*bt*ht^3 + (1/2)*bpzt*ht^2*hn - (1/2)*bpzt*ht*hn^2 + (2/3)*bpzt*hn^3
area = (bt*ht - 2*hn*bt + 2*bpzt*hn);
You are using the symbolic math toolbox. You have to convert any symbolic variable back to a numerical one. Use double(area) to get a double value of your symbolic variable area. You can use the function single, too.
But be aware that hn has to get a value first, otherwise it cannot be determined.
Documentation: http://www.mathworks.com/help/symbolic/double.html
To format this output, use the usual Matlab tools. In your case format short e
More details: http://www.mathworks.com/help/matlab/matlab_prog/display-format-for-numeric-values.html
In R2014b, this line:
inertia = (1/12)*bt*ht^3 + (1/2)*bpzt*ht^2*hn - (1/2)*bpzt*ht*hn^2 + (2/3)*bpzt*hn^3
returns
(13*hn^3)/2500 - (863307622649607*hn^2)/73786976294838206464 + (5304162033559185*hn)/151115727451828646838272 + 5527208847278085/77371252455336267181195264
which is a symbolic expression with numeric values represented exactly as rational fractions (even though they may have started out as decimal values in your code). You can convert this using vpa
vpa(inertia)
which returns:
0.0052*hn^3 - 0.000011699999999999999788190263583232*hn^2 + 0.000000035099999999999996664653271376613*hn + 0.000000000071437500000000005341045287673881
The length/precision of the decimal values depends on digits. Displaying this in an exponential-style format (xxe-x) is not an option for any symbolic math expression or value unless you write your own function to parse the string and do the conversion.
To convert this to a vectorized double-precision floating point function, you can use the terribly-named matlabFunction – matlabFunction(inertia) returns:
#(hn)hn.*3.51e-8-hn.^2.*1.17e-5+hn.^3.*5.2e-3+7.143750000000001e-11
But if you're doing this, I'd wonder why you were working with symbolic math in the first place and if it's possible to do everything in much faster double precision.
Keep in mind that if you want to convert to any kind of decimal form, variable precision or floating-point, in many cases you will lose precision. However, if you just want to view the result or perform fourth calculations if double precision, then it should be fine.
In 64 bits platform, the double's range are following:
-2.22507e-308 ~ +2.22507e-308
-1.79769e+308 ~ +1.79769e+308
and I followed the IEEE754 standard and tried to calculate the double's range by following equation,
x = (-1)^s * (1+fraction) * 2^(exponent-bias)
So I tried to calculate in 64 bits platform, but I am not sure the following whether it is right?
Since the bias is 1024, the max value of double can be calculated by following:
(1-2^-52) * 2^(2^11 - 1024) = 2.22507e-308
It seems right...
but when I calculate the min value of double by the same way
(1-2^-52) * 2^-(1024-1)) = 1.1125369292536007e-308,
1024 -1 (minus 1 is for zero bit?))
the result is not correct... so I wonder what is correct way to calculate double's range by hand.
Thank in advance.
Max (substitute any sensible type):
std::numeric_limits<double>::max()
Min (called "lowest" in C++11 because min meant something else, see comments):
std::numeric_limits<double>::lowest()