I would like to convert a number in base 10 with fraction to a number in base 16.
var myno = 28.5;
var convno = myno.toString(16);
alert(convno);
Try this:
Reverse the steps to convert back.
A simple example:
Convert decimal 23.5 into hex, and want one digit after the decimal point after conversion.
23.5 x 16 = 376.
Converted to hex = 0x178.
Answer in base 16: 17.8
Now convert back to decimal:
Take out the decimal point: 0x178
Convert to decimal: 376
Divide by 16: 23.5
I'm not sure what hexadecimal format you wanted to parse there, was this something like: "a1.2c"?
Floats are commonly stored in hexadecimal format using IEEE 754 standard. That standard doesn't use any dots (which don't exist in pure hexadecimal alphabet). Instead of that there are 3 groups of bits of predefined length (1 + 8 + 23 = 32bits in total ─ double uses 64bits).
I've written the following function for parsing such a numbers into float:
function hex2float(num) {
var sign = (num & 0x80000000) ? -1 : 1;
var exponent = ((num >> 23) & 0xff) - 127;
var mantissa = 1 + ((num & 0x7fffff) / 0x7fffff);
return sign * mantissa * Math.pow(2, exponent);
}
I combined Mark's and Kent's answers to make an overloaded parseFloat function that takes an argument for the radix (much simpler and more versatile):
function parseFloat(string, radix)
{
// Split the string at the decimal point
string = string.split(/\./);
// If there is nothing before the decimal point, make it 0
if (string[0] == '') {
string[0] = "0";
}
// If there was a decimal point & something after it
if (string.length > 1 && string[1] != '') {
var fractionLength = string[1].length;
string[1] = parseInt(string[1], radix);
string[1] *= Math.pow(radix, -fractionLength);
return parseInt(string[0], radix) + string[1];
}
// If there wasn't a decimal point or there was but nothing was after it
return parseInt(string[0], radix);
}
Another possibility is to parse the digits separately, splitting the string up in two and treating both parts as ints during the conversion and then add them back together.
function parseFloat(str, radix)
{
var parts = str.split(".");
if ( parts.length > 1 )
{
return parseInt(parts[0], radix) + parseInt(parts[1], radix) / Math.pow(radix, parts[1].length);
}
return parseInt(parts[0], radix);
}
var myno = 28.4382;
var convno = myno.toString(16);
var f = parseFloat(convno, 16);
console.log(myno + " -> " + convno + " -> " + f );
Try this.
string may be raw data(simple text) with 4 chars(0 - 255) or hex string "0xffffffff" 4 bytes length
jsfiddle.net
var str = '0x3F160008';
function parseFloat(str) {
var float = 0, sign, order, mantiss,exp,
int = 0, multi = 1;
if (/^0x/.exec(str)) {
int = parseInt(str,16);
}else{
for (var i = str.length -1; i >=0; i -= 1) {
if (str.charCodeAt(i)>255) {
console.log('Wrong string parametr');
return false;
}
int += str.charCodeAt(i) * multi;
multi *= 256;
}
}
sign = (int>>>31)?-1:1;
exp = (int >>> 23 & 0xff) - 127;
mantissa = ((int & 0x7fffff) + 0x800000).toString(2);
for (i=0; i<mantissa.length; i+=1){
float += parseInt(mantissa[i])? Math.pow(2,exp):0;
exp--;
}
return float*sign;
}
Please try this:
function hex2dec(hex) {
hex = hex.split(/\./);
var len = hex[1].length;
hex[1] = parseInt(hex[1], 16);
hex[1] *= Math.pow(16, -len);
return parseInt(hex[0], 16) + hex[1];
}
function hex2dec(hex) {
hex = hex.split(/\./);
var len = hex[1].length;
hex[1] = parseInt(hex[1], 16);
hex[1] *= Math.pow(16, -len);
return parseInt(hex[0], 16) + hex[1];
}
// ----------
// TEST
// ----------
function calc(hex) {
let dec = hex2dec(hex);
msg.innerHTML = `dec: <b>${dec}</b><br>hex test: <b>${dec.toString(16)}</b>`
}
let init="bad.a55";
inp.value=init;
calc(init);
<input oninput="calc(this.value)" id="inp" /><div id="msg"></div>