Convert two hexadecimal strings into datetime object - matlab

I have a hex number (uint32) stored as a character string. The character string is 'DA5CE697'. I want to convert this to a normal hex number on which I can perform some hex arithmetic operations. Are there any functions that can do this in matlab (like str2num for normal numbers)? Or if there is any other way of going about it?
Update
The character string provided above is the first part of an NTP timestamp. I am using:
datetime(t1 + 1/t2, 'ConvertFrom', 'epochtime', 'epoch', '1900-01-01')
To get the exact time from a data file. Both t1 and t2 are 4 bytes. The values for them are:
t1 = 'DA5CE697';
t2 = '7F14FCE7';
Ideally, I could have gone about reading 4 bytes at once and get the values for t1 and t2. But I have to traverse the file 1 byte at a time (some constraints). So, I am stitching back the values for t1 and t2 (to avoid missing zeros. Otherwise, it stores '05' as '5').

Your string is a hexadecimal representation of your uint32 number. If you instead want the integer (decimal) version of your hexadecimal string, you will need to convert it using hex2dec to be able to perform arithmetic within MATLAB.
f = hex2dec('DA5CE697')
%// 3663521431
Alternately, if you want your hexadecimal value to be cast as a floating point number you can instead use hex2num.
MATLAB does not have a hexadecimal datatype so I'm not sure what "hexadecimal arithmetic" you're expecting to be able to perform.
Update
Now that you have provided more information, you will combine t1 and t2 into a time stamp using hex2dec on both of them (as I showed above) and then perform the arithmetic using the decimal values.
t1 = 'DA5CE697';
t2 = '7F14FCE7';
datetime(hex2dec(t1) + 1/hex2dec(t2), 'ConvertFrom', 'epochtime', 'epoch', '1900-01-01')
%// 03-Feb-2016 20:50:31

Related

Precision of double values in Spark

I am reading some data from a CSV file, and I have custom code to parse string values into different data types. For numbers, I use:
val format = NumberFormat.getNumberInstance()
which returns a DecimalFormat, and I call parse function on that to get my numeric value. DecimalFormat has arbitrary precision, so I am not losing any precision there. However, when the data is pushed into a Spark DataFrame, it is stored using DoubleType. At this point, I am expecting to see some precision issues, however I do not. I tried entering values from 0.1, 0.01, 0.001, ..., 1e-11 in my CSV file, and when I look at the values stored in the Spark DataFrame, they are all accurately represented (i.e. not like 0.099999999). I am surprised by this behavior since I do not expect a double value to store arbitrary precision. Can anyone help me understand the magic here?
Cheers!
There are probably two issues here: the number of significant digits that a Double can represent in its mantissa; and the range of its exponent.
Roughly, a Double has about 16 (decimal) digits of precision, and the exponent can cover the range from about 10^-308 to 10^+308. (Obviously, the actual limits are set by the binary representation used by the ieee754 format.)
When you try to store a number like 1e-11, this can be accurately approximated within the 56 bits available in the mantissa. Where you'll get accuracy issues is when you want to subtract two numbers that are so close together that they only differ by a small number of the least significant bits (assuming that their mantissas have been aligned shifted so that their exponents are the same).
For example, if you try (1e20 + 2) - (1e20 + 1), you'd hope to get 1, but actually you'll get zero. This is because a Double does not have enough precision to represent the 20 (decimal) digits needed. However, (1e100 + 2e90) - (1e100 + 1e90) is computed to be almost exactly 1e90, as it should be.

How can i write a number values in powers of 10? [duplicate]

This question already has answers here:
What is the Small "e" in Scientific Notation / Double in Matlab
(2 answers)
Closed 7 years ago.
How can I write a number/Integer value to power of 10, e.g. 1000 as 10^3? I am writing code whose output is a string of very large numbers. My output in longEng format is:
4.40710646596169e+018
16.9749211806197e+186
142.220634811050e+078
508.723835280617e+204
1.15401317731033e-177
129.994388899690e+168
14.3008811642810e+153
1.25899227268954e+165
24.1450064703939e+150
627.108997290435e+144
2.03728822649372e+177
339.903986115177e-066
150.360900017430e+183
5.39003779219462e+135
183.893417489826e+198
648.544709490386e+045
19.7574461055182e+198
3.91455750674308e+102
6.41548629454028e-114
70.4943280639616e+096
19.7574461055182e+198
3.11450571506133e-009
249.857950606210e+093
4.64921904682151e+180
750.343029004712e+147
I want these results to be in a format of power of 10, so that I can easily do arithmetic operations for my next function.
you can write format shortE and see you output like this:
4.4071e+18
1.6975e+187
1.4222e+80
5.0872e+206
If you only want to print the data in scientific format, the Matlab itself can do this for you.
If you can to obtain the scientific notation form as
a * 10^b,
i.e., obtain the coefficient a and the exponent b, you can first obtain the b as:
b = floor(log10(abs(x)));
then the a as:
a = x * 10^(-b);
from my understanding you wish to take your number e.g. 4.40710646596169e+018 and split it up into:
4.40710646596169 and 018 once you have them separated you you can perform operations as you wish.
You can even join them back to look like: 4.40710646596169^018 if you so desire (although to look like that they would be strings and therefore mathematical operations on the number would be NAN).
Since e represents to the power 10 and is present in all numbers you listed this is a simple process with many solutions, here is one.
% format long is very important otherwise it will appear to you that you have
%lost precision. MATLAB hides precision from view to save screen space and to
%produce less confusing results to the viewer. (the precision is still there but
%with format long you will be able to see it.
format long
x = 4.40710646596169e+018;
%convert your number into a string, this will allow you to split the number based
%on the always present e+ 'delimiter' (not really a delimiter but looks like one')
s = num2str(x);
%use strsplit to perform the split in the required place. it will output a 1x2
%cell
D = strsplit(s, {'e+'});
%extract each cell to a separate variable. in fact D{1} can be directly used for
%the input of the next function.
D11 = D{1};
D22 = D{2};
%convert the separated strings back into numbers with double precision (keep
%maintin value accuracy)
D1 = str2double(D11)
D2 = str2double(D22)
in order to do this operation on an entire column vector it is simply a matter of using a for loop to iterate through all the numbers you have.

Matlab reading 24-bit ascii-hex file into a 32-bit signed

I'd like to plot every 9th element from an ascii file containg a single column of 24-bit signed hex values
ex.
813457
123456
241566
etc..
The problem is, I can't get Matlab to treat values 800000-FFFFFF as negative, presumably because it's not sign extending it into 32-bits.
I thought of breaking it up into strings, then converting, but sscanf requires the '0x' to convert signed %i hex values so I'm forced to use unsigned:
C = textscan(fp, '%s') %generates 16380x1 cell (instead of normal array?!)
sscanf (C{1,1}{1,1}, '%x') %convert first ascii hex element from cell to unsigned hex
Interestingly, as a test, just doing hex2dec('FFC00000') results in a postive number, how can I force all the ascii lines in the file to be imported as an array of signed 24 or 32bit data?
To do the conversion you need, you can follow these steps:
Convert from hex string to a positive integer of double type, using herx2dec, as you've already done.
Convert that value to uint32 type.
Interpret that uint32 value as an int32 (convert data type without changing underlying data), using typecast.
Example:
>> typecast(uint32(hex2dec('FFC00000')),'int32')
ans =
-4194304

How to fscanf a combination of float and string?

The data is like this
5.1,3.5,1.4,0.2,Iris-setosa
while I read it using this
data = fscanf(file, '%f,%f,%f,%f,%s');
and it turned out that data is an array of float rather than a combination of float and string. So how do I read this data from txt?
From the Matlab docs for fscanf:
Output Arguments A: An array. If the format includes:
Only numeric specifiers, A is numeric. ... Only character or
string specifiers (%c or %s), A is a character array. ... A
combination of numeric and character specifiers, A is numeric, of
class double. MATLAB converts each character to its numeric
equivalent. This conversion occurs even when the format explicitly
skips all numeric values (for example, a format of '%*d %s').
So your best bet is to read everything in as strings, and then convert the numeric strings to numeric values, using str2num or str2double or similar.
Alternatively, since you know there are 4 floating point values that really store a floating point value, and then the rest store the numeric ASCII values for the string, you can always split up your data and cast the part you know should be a string to char. Something like:
flt = data(1:4);
str = char(data(5:end));

Ab Initio - Formatting a number in Left alignment

I have a requirement in Ab Initio to format a number in left alignment. I shouldn't be using String conversion (as Strings are left aligned by default), as it might cause compatibility problems in the other end.
For example, if my Field has 7 bytes length, and I'm getting only two digits as my input, then these two digits should go into the first two bytes of my field (left aligned), instead of the last two bytes.
So, is there any in-built function in Ab Initio, that can format a number as left aligned?
You can convert it to string and let it ride. Ab Initio will automatically convert between string and decimal. Also, the physical representation will be the same for these two types.
If you are trying to use a non-ascii based format (int, float, etc.) I don't think there is a built-in function for this and you will probably have to do something rough like cast it to a void type then to a string type using hex_to_string() to preserve the exact bits and then right pad with spaces.