I have tried this
function binToDec(num) {
let dec = 0;
for(let i = 0; i < num.length; i++) {
if(num[num.length - (i + 1)] === '1') {
dec += 2 ** i;
}
}
return dec;
}
console.log(binToDec('1010'));
this code is not mine and it works but i want to know how it converts the binary number to decimal and it will be very helpful is you could tell me another way to do it.
I have also tried this
function binToDec(num) {
let bin = parseInt(num, 2);
return bin;
}
console.log(binToDec(1010));
I know this also work but i am not looking for this answer.
thank you for your help.
I just starts with the last character of the string and adds the value of this position to the result.
string dec
------ -------
1010 0
0 0
1 0 + 2
0 2
1 2 + 8
------ ------
10
function binToDec(num) {
let dec = 0;
for (let i = 0; i < num.length; i++) {
if (num[num.length - (i + 1)] === '1') {
dec += 2 ** i;
}
}
return dec;
}
console.log(binToDec('1010')); // 10
Another way is to start with the left side of the sting and
multiply the converted value by the base (2) and
add the value of the string.
The result is now the converted number. This works for all bases, as long as the value at the index is converted to a number.
function binToDec(num) {
let dec = 0;
for (let i = 0; i < num.length; i++) {
dec *= 2;
dec += +num[i];
}
return dec;
}
console.log(binToDec('1101')); // 13
Explanation
Think of how base 10 works.
909 = 900 + 9
= (9 * 100) + (0 * 10) + (9 * 1)
= (9 * 10**2) + (0 * 10**1) + (9 * 10**0)
As you can see, a natural number in base 10 can be seen as a sum where each term is in the form of:
digit * base**digit_position
This is true for any base:
base 2 : 0b101 = (0b1 * 2**2) + (0b0 * 2**1) + (0b1 * 2**0)
base 16 : 0xF0F = (0xF * 16**2) + (0x0 * 16**1) + (0xF * 16**0)
Therefore, here is a possible abstraction of a natural number:
function natural_number (base, digits) {
var sum = 0;
for (var i = 0; i < digits.length; i++) {
digit = digits[i];
digit_position = digits.length - (i + 1);
sum += digit * base**digit_position;
}
return sum;
}
> | natural_number(2, [1, 0, 1]) // 1 * 2**2 + 1 * 2**0
< | 5
> | natural_number(10, [1, 0, 1]) // 1 * 10**2 + 1 * 10**0
< | 101
> | natural_number(16, [1, 0, 1]) // 1 * 16**2 + 1 * 16**0
< | 257
Your own function takes only binary numbers (base 2). In this case digit can be either 0 or 1, that's all. We know that it's useless to multiply something by 0 or 1, so the addition can be replaced with:
if (digit === 1) {
sum += 2**digit_position;
}
Which is the equivalent of:
if (num[num.length - (i + 1)] === '1') {
dec += 2 ** i;
}
Do you get it? :-)
Alternative
You don't feel confortable with the exponentiation operator (**)? There is a workaround. Did you ever notice that multiplying a number by 10 is nothing more than shifting its digits one time to the left?
909 * 10 = 9090
Actually, shifting a number to the left boils down to multiplying this number by its base:
number *= base
This is true for any base:
base 2 : 0b11 * 2 = 0b110
base 16 : 0xBEE * 16 + 0xF = 0xBEE0 + 0xF = 0xBEEF
Based on this, we can build an algorithm to convert an array of digits into a number. A trace of execution with [9,0,9] in base 10 as input would look like this:
init | 0 | n = 0
add 9 | 9 | n += 9
shift | 90 | n *= 10
add 0 | 90 | n += 0
shift | 900 | n *= 10
add 9 | 909 | n += 9
Here is a possible implementation:
function natural_number (base, digits) {
var n = 0;
for (var i = 0; i < digits.length; i++) {
n += digits[i];
if (i + 1 < digits.length) {
n *= base;
}
}
return n;
}
Of course this function works the same as before, and there is a good reason for that. Indeed, unroll the for loop that computes [9,0,9] in base 10, you get this:
return ((0 + 9) * 10 + 0) * 10 + 9;
Then expand this expression:
((0 + 9) * 10 + 0) * 10 + 9
= (0 + 9) * 10 * 10 + 0 * 10 + 9
= 9 * 10 * 10 + 0 * 10 + 9
= 9 * 10**2 + 0 * 10**1 + 9 * 10**0
Do you recognize the equation discussed earlier? :-)
Bonus
Reverse function:
function explode_natural_number (base, number) {
var remainder, exploded = [];
while (number) {
remainder = number % base;
exploded.unshift(remainder);
number = (number - remainder) / base;
}
return exploded.length ? exploded : [0];
}
> | explode_natural_number(2, 5)
< | [1, 0, 1]
> | explode_natural_number(3, 5) // base 3 (5 = 1 * 3**1 + 2 * 3**0) :-)
< | [1, 2]
> | explode_natural_number(16, natural_number(16, [11, 14, 14, 15])) // 0xBEEF
< | [11, 14, 14, 15]
String to number and number to string:
function parse_natural_number (number, base) {
var ZERO = 48, A = 65; // ASCII codes
return natural_number(base, number.split("").map(function (digit) {
return digit.toUpperCase().charCodeAt(0);
}).map(function (code) {
return code - (code < A ? ZERO : A - 10);
}));
}
function stringify_natural_number (number, base) {
var ZERO = 48, A = 65; // ASCII codes
return String.fromCharCode.apply(
String, explode_natural_number(base, number).map(function (digit) {
return digit + (digit < 10 ? ZERO : A - 10);
})
);
}
> | stringify_natural_number(parse_natural_number("48879", 10), 16)
< | "BEEF"
> | parse_natural_number("10", 8)
< | 8
More levels of abstraction for convenience:
function bin_to_dec (number) {
return parse_natural_number(number, 2);
}
function oct_to_dec (number) {
return parse_natural_number(number, 8);
}
function dec_to_dec (number) {
return parse_natural_number(number, 10);
}
function hex_to_dec (number) {
return parse_natural_number(number, 16);
}
function num_to_dec (number) {
switch (number[0] + number[1]) {
case "0b" : return bin_to_dec(number.slice(2));
case "0x" : return hex_to_dec(number.slice(2));
default : switch (number[0]) {
case "0" : return oct_to_dec(number.slice(1));
default : return dec_to_dec(number);
}
}
}
> | oct_to_dec("10")
< | 8
> | num_to_dec("010")
< | 8
> | 010 // :-)
< | 8
function dec_to_bin (number) {
return stringify_natural_number(number, 2);
}
> | dec_to_bin(8)
< | "1000"
Related
const reversedNum = num =>
parseFloat(num.toString().split('').reverse().join('')) * Math.sign(num)
console.log(reversedNum(456))
Couldn't figure it out how to write code in order to sum 654 + 456
Thank You very much!
const reversedNum = num => num + +num.toString().split('').reverse().join('')
You can return sum of num and reversedNum inside a function.
const sumOfNumAndReversedNum= num => {
const reversedNum = parseFloat(num.toString().split('').reverse().join('')) * Math.sign(num)
return num + reversedNum
}
let userNumber = 456
console.log(sumOfNumAndReversedNum(userNumber))
You can write a more performant way of reversing the number than turning it into a string, flipping it, and turning it back into an integer.
One option is to go through the number backwards by popping off the last integer (e.g., 123 % 10 === 3) and adding it to your newly reversed number. You'll also need to multiply your reversed number by 10 in each iteration to move you to the next degree.
For example, given the number 123:
123 % 10 = 3;
123 /= 10 = 12;
0 * 10 + 3 = 3;
1 % 10 = 2;
12 /= 10 = 1;
3 * 10 + 2 = 32
1 % 10 = 1;
1 /= 10 = 0;
32 * 10 + 1 = 321
This method will also automatically take care of negative numbers for you, leaving you something like:
function reverse(num) {
let reversed = 0;
while (num !== 0) {
const popped = num % 10;
num = parseInt(num / 10);
if (reversed > Number.MAX_VALUE / 10 || (reversed === Number.MAX_VALUE / 10 && popped > 7)) return 0;
if (reversed < Number.MIN_VALUE / 10 || (reversed === Number.MIN_VALUE / 10 && popped < -8)) return 0;
reversed = reversed * 10 + popped;
}
return reversed;
}
Now you can simply call:
console.log(123 + reverse(123))
const reversedNum = num =>
Number(num.toString().split('').reverse().join(''))
console.log(reversedNum(456))
Do it!
Question : Given n, take the sum of the digits of n. If that value has
more than one digit, continue reducing in this way until a
single-digit number is produced. The input will be a non-negative
integer. Ex- 16 --> 1 + 6 = 7 942 --> 9 + 4 + 2 = 15 --> 1 +
5 = 6 132189 --> 1 + 3 + 2 + 1 + 8 + 9 = 24 --> 2 + 4 = 6 493193
--> 4 + 9 + 3 + 1 + 9 + 3 = 29 --> 2 + 9 = 11 --> 1 + 1 = 2
function digitalroot(n) {
let a = n;
var sum = 0;
while(a >= 1){
sum += a % 10;
a = Math.trunc(a/10)
}
if(sum > 9){
digitalroot(sum)
}
console.log("Print")
console.log(sum)
return sum
}
I tried above code but not getting correct output with below called input
With this two inputs passed in function: (16), (456)
O/P:
Print
7
Print
6
Print
15
Please help me, I am new to JavaScript
you forgot to return value from function call inside that sum>9 condition.
check recursion here : w3School
function digitalroot(n) {
let a = n;
var sum = 0;
while(a >= 1){
sum += a % 10;
a = Math.trunc(a/10)
}
if(sum > 9){
return digitalroot(sum)
}
return sum
}
console.log(digitalroot(493193));
Check this working example
function digitalroot(n){
console.log(`Value of n = ${n}`)
var digits = (""+n).split("");
for (var i = 0; i < digits.length; i++) {
digits[i] = +digits[i];
}
var finalVal = digits
let result = finalVal.reduce((a, b) => a + b, 0)
console.log(`Final Value with list ${result}`)
}
digitalroot(289)
For example digits=4 means if input is 7 need output 7999, for 83 output should be 8399, for 9 output should be 9999. Want to add trailing 9 based on digits
You could take the stringes number and pad the needed values.
function nines(value, digits) {
return +value.toString().padEnd(digits, 9);
}
console.log(nines(83, 4));
A numerical version
function nines(value, digits) {
while (value < 10 ** (digits - 1)) value = value * 10 + 9;
return value;
}
console.log(nines(83, 4));
console.log(nines(2, 1));
console.log(nines(2, 2));
One thing you may be able to do is to multiply the input number by a power of 10 in order to add extra digits of 0 to the end, and then use addition to add 9 into each of those newly created digits.
For example:
Input - 7
7 * 1000 -> 7000 (NOTE: 1000 is a power of 10: 10^3)
7000 + (100 * 9) + (10 * 9) + (1 * 9) = 7999
Input
83 * 100 -> 8300 (NOTE: 100 is a power of 10: 10^2)
8300 + (10 * 9) + (1 * 9) = 8399
Not entirely sure if this is what you want
trailNines(number) {
let numberString = number.toString();
let result = '';
if(numberString.length === 4){
result = number.toString();
}
if(numberString.length === 3) {
result = number.toString() + '9';
}
if(numberString.length === 2) {
result = number.toString() + '99';
}
if(numberString.length === 1) {
result = number.toString() + '999';
}
return parseInt(result);
}
I have an Athena 16C controller that I am controlling via RS232. Its messaging protocol requires a proprietary checksum:
"CHKSUM: This is a two character Message Code Numbering System, representing the sum of all the ASCII values of all the characters (excluding the START, CHAR, the END CHAR, and the CHKSM themselves) in the message. The sum is computed using the following formula:
CHKSM = SUM(All Message Characters)%256 where % represents the modulus operator."
An example message (from their documentation) is this:
$Ø1Ø1RØ5C1<CR>
and can be broken down as:
$ [START CHAR] 01 [ID] 01 [ZONE] R [TYPE] 05 [PARAM] C1 [CHKSM] <CR> [END CHAR]
I have sent this message to the controller and it works as expected.
I am writing my code in JS and have the following that is supposed to calculate the CHKSM to put at the end of the message:
var sum = 'Ø1Ø1RØ5'
.split('')
.map(function(char) {
return char.charCodeAt(0);
})
.reduce(function(current, previous) {
return previous + current;
});
var chksm = (sum % 256);
console.log(chksm.toString(16));
The checksum should be 'C1' according to the message format. But the calculated sum is 377 which results in a checksum of 121 which equals 79 in hex.
// 0 = 48, 1 = 49, R = 82, 5 = 53 (ASCII values)
// 48 + 49 + 48 + 49 + 82 + 48 + 53 = 377
// 377 % 256 = 121 (decimal) = 79 (hex)
An engineer from Athena sent me the following VB code but I cannot understand the logic, nor the syntax particularly. Is there something basic I am missing with this problem in general?
' Covert the mod % 256 checksum to the 2 chars:
' Will set First and Second chars for encoded value. Pass in the value (Checksum mod 256)
' and where to return the 1st and 2nd chars to.
Public Sub EncodeIt(ByVal Value As Integer, ByRef FirstChar As Integer, ByRef SecondChar As Integer)
If Value > 359 Then 'Z9 = 359, absolute max possible
Value = 359
End If
'Note: backslash '\' means integer divide, not floating point!!
If Value > 99 Then
FirstChar = (Value \ 10) + 65 - 10 '65 = ascii "A"
Else
FirstChar = (Value \ 10) + 48 '48 = ascii "0"
End If
SecondChar = (Value Mod 10) + 48
End Sub
' Convert the two chars received in a message back to normal integer.
' Take the 2 chars and return a decoded integer value
Public Function DecodeIt(ByVal FirstChar As Integer, ByVal SecondChar As Integer) As Integer
'65 = ascii "A", 48 = ascii "0"
If FirstChar > 57 Then '57 = ascii "9"
Return ((FirstChar - 65 + 10) * 10) + (SecondChar - 48)
Else
Return ((FirstChar - 48) * 10) + (SecondChar - 48)
End If
End Function
The encoding from decimal to string is cutom made and not base16. This is why (121).toString(16) is not equal to C1.
From the VBA of your post the encoding/decoding functions should be:
function compute_checksum(message) {
var sum = 0;
for(var i=0; i<message.length; i++)
sum += message.charCodeAt(i);
return sum % 256;
}
function encode_checksum(value) {
value = Math.min(value, 359);
var c1 = ((value / 10) | 0) + (value > 99 ? 55 : 48);
var c2 = (value % 10) + 48;
return String.fromCharCode(c1, c2);
}
function decode_checksum(text) {
var c1 = text.charCodeAt(0);
var c2 = text.charCodeAt(1);
return (c1 > 57 ? c1 - 55 : c1 - 48) * 10 + (c2 - 48)
}
Here is a usage example:
var checksum = compute_checksum('0101R05');
console.log('checksum: ' + checksum);
var CHKSM = encode_checksum(checksum);
console.log('encoded checksum: ' + CHKSM);
console.log('decoded checksum: ' + decode_checksum(CHKSM));
I just went through this for C# and with the help of above, came up with this code that works (for me):
'reqtemp' is the string that contains controller ID#, Zone, Parameter, etc. without the start and checksum characters.
// generate checksum for Athena
int x = 0;
int sl = reqtemp.Length;
int FirstChar = 0; //checksum 1st character
int SecondChar = 0; //checksum 2nd char
string crcr; // crc for requests
for (int c = 0; c < sl; c++)
{
string sel = reqtemp.Substring(c, 1);
x = x + Convert.ToChar(sel);
}
x = x % 256; //modular 256
x = Math.Min(x, 359); // don't allow > 359
if (x > 99)
{ FirstChar = (x / 10) + 65 - 10; }
else
{ FirstChar = (x / 10) + 48; }
SecondChar = (x % 10) + 48;
crcr = Char.ConvertFromUtf32(FirstChar) + Char.ConvertFromUtf32(SecondChar);
// MessageBox.Show(crcr);
string reqtempfull = "$"+ reqtemp + crcr + (char)13;
crc.Text = reqtempfull; //display the full sp string
if (ComPort.IsOpen)
{
ComPort.Write(reqtempfull); // send it`enter code here`
}
Is there any faster alternative to the following expression:
Math.pow(2,Math.floor(Math.log(x)/Math.log(2)))
That is, taking the closest (smaller) integer power of 2 of a double? I have such expression in a inner loop. I suspect it could be much faster, considering one could just take the mantissa from the IEEE 754 representation of the double.
Making use of ES6's Math.clz32(n) to count leading zeros of a 32-bit integer:
// Compute nearest lower power of 2 for n in [1, 2**31-1]:
function nearestPowerOf2(n) {
return 1 << 31 - Math.clz32(n);
}
// Examples:
console.log(nearestPowerOf2(9)); // 8
console.log(nearestPowerOf2(33)); // 32
Here's another alternative, with benchmarks. While both seems to be comparable, I like being able to floor or ceil.
function blpo2(x) {
x = x | (x >> 1);
x = x | (x >> 2);
x = x | (x >> 4);
x = x | (x >> 8);
x = x | (x >> 16);
x = x | (x >> 32);
return x - (x >> 1);
}
function pow2floor(v) {
var p = 1;
while (v >>= 1) {
p <<= 1;
}
return p;
}
function pow2ceil(v) {
var p = 2;
while (v >>= 1) {
p <<= 1;
}
return p;
}
function MATHpow2(v) {
return Math.pow(2, Math.floor(Math.log(v) / Math.log(2)))
}
function nearestPowerOf2(n) {
return 1 << 31 - Math.clz32(n);
}
function runner(fn, val) {
var res;
var st = new Date().getTime()
for (var i = 0; i < 100000000; i++) {
fn(val);
}
return (new Date().getTime() - st)
}
var source = 300000;
var a = runner(pow2floor, source);
console.log("\n--- pow2floor ---");
console.log(" result: " + pow2floor(source));
console.log(" time: " + a + " ms");
var b = runner(MATHpow2, source);
console.log("\n--- MATHpow2 ---");
console.log(" result: " + MATHpow2(source));
console.log(" time: " + b + " ms");
var b = runner(nearestPowerOf2, source);
console.log("\n--- nearestPowerOf2 ---");
console.log(" result: " + nearestPowerOf2(source));
console.log(" time: " + b + " ms");
var b = runner(blpo2, source);
console.log("\n--- blpo2 ---");
console.log(" result: " + blpo2(source));
console.log(" time: " + b + " ms");
// pow2floor: 1631 ms
// MATHpow2: 13942 ms
// nearestPowerOf2: 937 ms
// blpo2 : 919 ms **WINNER**
Here is also a branchless 32 bit version which is the fastest (9x) (on cellphones even more!) as of now.
It can also be scaled to 64 or 128 bits adding 1 or two lines:
x = x | (x >> 64);
x = x | (x >> 128);
on my computer:
2097152,blpo2: 118 ms **FASTEST**
2097152,nearestPowerOf2: 973 ms
2097152,pow2floor: 2033 ms
on my phone:
2097152,blpo2: 216 ms **FASTEST**
2097152,nearestPowerOf2: 1259 ms
2097152,pow2floor: 2904 ms
function blpo2(x) {
x = x | (x >> 1);
x = x | (x >> 2);
x = x | (x >> 4);
x = x | (x >> 8);
x = x | (x >> 16);
x = x | (x >> 32);
return x - (x >> 1);
}
function pow2floor(v) {
var p = 1;
while (v >>= 1) {
p <<= 1;
}
return p;
}
function nearestPowerOf2(n) {
return 1 << 31 - Math.clz32(n);
}
function runner(fn, val) {
var res;
var st = new Date().getTime()
for (var i = 0; i < 100000000; i++) {
res = fn(val);
}
dt = new Date().getTime() - st;
return res + "," + fn.name + ": " + dt + " ms"
}
var source = 3000000;
console.log(runner(blpo2, source), "**FASTEST**")
console.log(runner(nearestPowerOf2, source))
console.log(runner(pow2floor, source))
Unfortunately, you would need an equivalent of the C function frexp. The best I've been able to find is in JSFiddle, and its code uses Math.pow.
There are a couple of alternatives you could benchmark, using real data, along with your current attempt:
Starting at 1.0, multiply repeatedly by 2.0 until it is greater than or equal to the input, then multiply by 0.5 until it is less than or equal to the input. You would need special handling for values at the ends of the double range.
Store an ascending value array of all the exact powers of two in the double range, and do a binary search.
The first one is likely to be fastest if your data is typically close to 1.0. The second one requires up to 11 conditional branches.
Without ES6...
x=Math.floor(Math.random()*500000); //for example
nearestpowerof2=2**(x.toString(2).length-1);
console.log(x,">>>",nearestpowerof2);
In other words: the result is 2 to the power of the length of the binary representation of the number subtracted by 1.
And this is another.
function nP2(n) {
return 1 << Math.log2(n);
}
console.log(nP2(345367));
console.log(nP2(34536));
console.log(nP2(3453));
console.log(nP2(345));
console.log(nP2(34));
And another way (this one is slow but it's fun to code recursive ones):
function calc(n, c) {
c = c || 0;
n = n >> 1;
return (n > 0) ? calc(n, c + 1) : 2 ** c;
}
console.log(calc(345367));
console.log(calc(34536));
console.log(calc(3453));
console.log(calc(345));
console.log(calc(34));
Oh and I forgot the one-liner:
a=3764537465
console.log(2**~~Math.log2(a))
In other words, here we raise 2 to the power of the rounded logarithm in base 2 of the number. But alas, this is 140 times slower than the winner: blpo2 https://stackoverflow.com/a/74916422/236062