I'm wondering how radix calculation really works in parseInt.
I want to build a own formula/function to do exactly the same as parseInt, so that I can put it into another programming language or tell my students in my math class so that they can learn it (not that I would never do it).
I just want to know how it works.
I put together a little fiddle: http://jsfiddle.net/Cy6Bx/
EDIT just figure it out by myself here is the result: https://tinker.io/3ca4c
It dose not have all the validation and such that parseInt has, but it dose the basic things to understand whats going on
"I'm wondering how radix calculation really works in parseInt."
In fact, is not rocket science, the most simple parseInt implementation (agnostic to the language) would iterate the string (in reverse order) and multiply the radix factor by the character numeric value ('0' -> 0, '1' -> 1, ..., 'A' -> 10, ..., 'F' -> 15) raising the radix in every iteration
Something like:
value = 0
base = 1
for every character c in numeric_string (iterate in backwards)
var d = digitValueOf(c)
value = value + d * base
base = base * radix
end for
Related
The task is to write a function that takes n as an input where n is a number (from -32768 to 32768) and returns the square of that number. Simple task except for the fact that we cannot use any operators such as *,+ or even use any Math. functions such as pow. eval is not allowed as well.
Even more challenging is that we must keep the character code count less than 39 characters.
I absolutely cannot think of a way to get the square of a number without using the + or *. And even worse, to keep the character count less, it's impossible for me.
Codes like this won't work because: I used the plus sign and the character count is more than 60.
function sq(n){
var res=n;
for(i=1;i<n;i++)
res+=n;
return res;
}
If n is a decimal, we are expected to return the nearest whole number as the result.
Thank you for reading all of this!
Edit: My problem has been solved. Thank you to everyone who has tried to help me with their codes as it helped me gain a new aspect of solving each problems.
Thank you very much again!
You can try this as well
function multiply(a) {
return a / (1 / a);
}
console.log(multiply(6))
console.log(multiply(4))
The repeat() method returns a new string with a specified number of copies of the string it was called on. See here
This approach is limited to positive and integer numbers only.
// Another method
function multiplytwo(a) {
return ("i").repeat(a).repeat(a).length
}
console.log(multiplytwo(4))
console.log(multiplytwo(25))
//creating a string “i” and repeating it “a” times, then repeats that “a” times, and then returning the length.
You could divide n by 1 / n
For rounding off without using Math.round, I have used this:
s=n=>(r=>(r-~~r<.5?0:1)- -~~r)(n/(1/n))
console.log(s(5));
console.log(s(4.4));
console.log(s(-4.44));
This has 39 characters.
** is not in your list, so you might be able to use it:
sq = n => n ** 2
console.log(sq(5));
You could also use - twice, instead of +:
sq=n=>{s=0;for(let i=n;i>0;i--)s=s-(-n);return s}
console.log(sq(5));
(function definition is 49 characters)
If anyone still needs a solution that passes tests.
#adiga's solution works nicely. But if you need to be under 39 characters you can exploit JS implicit type coercion: substitute r-~~r<.5?0:1 by r-~~r<.5. It will give you a boolean which will be coerced to either 1 or 0. So, final solution is following:
s=n=>(r=>(r-~~r<.5)- -~~r)(n/(1/n))
As this just got brought back up, here is a 22-character solution:
sq=n=>~~-(-.5-n/(1/n))
;[[0, 0], [1, 1], [2, 4], [3, 9], [4.4, 19], [-4.44, 20], [32768, 1073741824]]
.forEach (([n, s]) => console .log (`sq(${n}) == ${s} //=> ${sq(n) == s}`))
Explanation
Like other answers here it takes advantage of the fact that n / (1/n) is mathematically equivalent to squaring n. This is also helped by the fact that although 1 / 0 is Infinity, 0 / Infinity gives back 0. Mathematically this is iffy, but for the problem it's perfect. The trick is then to round this to the nearest integer. We could do so like this:
let sq = (n) => Math .round(n / (1 /n) + 0.5)
But we have two issues here. First we take the fact that Math.round is disallowed by the rules. Here we can use a common substitution for Math.round, namely ~~. This is simply two consecutive applications of the bitwise NOT operator, which first removes any fractional part to convert the result to a 32-bit integer, then inverts all the bits. Doing it a second time acts much like integer truncation, giving something more like:
let sq = (n) => ~~ (n / (1 /n) + 0.5)
But we still have a + in the definition, also disallowed. But that can be replaced by subtracting the negation of the value, with a version like this:
let sq = (n) => ~~ (n / (1 /n) - -0.5)
Now, minifying this would give us
sq=(n)=>~~(n/(1/n)- -.5)
and this is an equivalent 22-character solution. But for some reason I really didn't like the space in that version, and since (a - b) is equivalent to - (b - a), we can create this alternative:
let sq=n=>~~-(-.5-n/(1/n))
I'm not generally much of a code-golfer. I simply don't see the point. But this was a fun little challenge.
I read some other's code, there is some piece of code below. I am wondering What does the method do with num?
formatNumber: function (num, digit) {
var pow = Math.pow(10, digit || 5);
return Math.round(num * pow) / pow;
}
BTW when I running
formatNum(11.267898, 5), it gave me 11.2679, is this OK?
Essentially, the function returns the number with certain precision. The precision is digit, which is 5 if not provided.
The return part essentially brings that many values (equal to digit) decimal right to left and then discard the rest and finally divides again to get the original value reduces to precision of digit.
Regarding BTW edit -
The value obtained is correct. See details below
When you call formatNum(11.267898, 5), you're asking the number to round to 5 digit precision and your number has 6 digit precision - precision is digits after the dot.
Now when you call num * pow the number becomes 1126789.8 and when you round this number, it rounds to closest integer which is 11.26790. Finally when you divide it by pow (100000), the number becomes 11.2679, discarding last 0 as trailing Zero in precision is pointless.
That is a really poor piece of code.
First, the naming conventions don't match what the code does at all.
The function name formatNumber() suggests that it formats a number. In other words, it ought to produce a string representation of a number, formatted in some way. But the function doesn't do this, it returns another number. That makes no sense. Numbers don't have a format, they are just numbers.
The parameter name digit sounds like it would contain a single digit. But it doesn't. It contains a count of digits that you want to round the number to. When you name things, singular and plural matter!
It gets worse.
As you found, the function doesn't even work. In your example, formatNum(11.267898,5) returns the number 11.2679. Why did it give you four digits when you asked for five? The result you were expecting was 11.26790, wasn't it? Well, of course that is identical to 11.2679, if we're talking about numbers. But what good does that do you when you wanted five digits?
Or to take a ridiculously simple example: formatNumber(1,2). You might expect that to produce 1.00, but it produces 1. Of course that is really the same value, but not formatted the way you want.
Now we go from the ridiculous to the sublime.
JavaScript has always had a built-in function that does exactly what we would expect formatNumber() to do: number.toFixed(digits). This does proper rounding and always returns the number of digits after the decimal point that you ask for. And of course, to be able to do that, it returns a string, not a number.
If we try these examples using .toFixed() they work as expected:
(11.267898).toFixed(5) returns the string "11.26790".
(1).toFixed(2) returns "1.00".
And so on, for just about anything you can throw at it. (It gives up on numbers with magnitude too large and uses exponential notation instead.)
Note that the parentheses around the first number in those examples are just needed to avoid a syntax error; in most cases you'd be using a variable and they would not be required, e.g.
myNumber.toFixed(2)
To summarize, not only does formatNumber() not do what it says and not anything useful, it was never needed in the first place!
I'm watching this Google I/O presentation from 2011 https://www.youtube.com/watch?v=M3uWx-fhjUc
At minute 39:31, Michael shows the output of the closure compiler, which looks like the code included below.
My question is what exactly is this code doing (how and why)
// Question #1 - floor & random? 2147483648?
Math.floor(Math.random() * 2147483648).toString(36);
var b = /&/g,
c = /</g,d=/>/g,
e = /\"/g,
f = /[&<>\"]/;
// Question #2 - sanitizing input, I get it...
// but f.test(a) && ([replaces]) ?
function g(a) {
a = String(a);
f.test(a) && (
a.indexOf("&") != -1 && (a = a.replace(b, "&")),
a.indexOf("<") != -1 && (a = a.replace(c, "<")),
a.indexOf(">") != -1 && (a = a.replace(d, ">")),
a.indexOf('"') != -1 && (a = a.replace(e, """))
);
return a;
};
// Question #3 - void 0 ???
var h = document.getElementById("submit-button"),
i,
j = {
label: void 0,
a: void 0
};
i = '<button title="' + g(j.a) + '"><span>' + g(j.label) + "</span></button>";
h.innerHTML = i;
Edit
Thanks for the insightful answers. I'm still really curious about the reason why the compiler threw in that random string generation at the top of the script. Surely there must be a good reason for it. Anyone???
1) This code is pulled from Closure Library. This code in is simply creating random string. In later version it has been replaced by to simply create a large random integer that is then concatenated to a string:
'closure_uid_' + ((Math.random() * 1e9) >>> 0)
This simplified version is easier for the Closure Compiler to remove so you won't see it leftover like it was previously. Specifically, the Compiler assumes "toString" with no arguments does not cause visible state changes. It doesn't make the same assumption about toString calls with parameters, however. You can read more about the compiler assumptions here:
https://code.google.com/p/closure-compiler/wiki/CompilerAssumptions
2) At some point, someone determined it was faster to test for the characters that might need to be replaced before making the "replace" calls on the assumption most strings don't need to be escaped.
3) As others have stated the void operator always returns undefined, and "void 0" is simply a reasonable way to write "undefined". It is pretty useless in normal usage.
1) I have no idea what the point of number 1 is.
2) Looks to make sure that any symbols are properly converted into their corresponding HTML entities , so yes basically sanitizing the input to make sure it is HTML safe
3) void 0 is essentially a REALLY safe way to make sure it returns undefined . Since the actual undefined keyword in javascript is mutable (i.e. can be set to something else), it's not always safe to assume undefined is actually equal to an undefined value you expect.
When in doubt, check other bases.
2147483648 (base 10) = 0x80000000 (base 16). So it's just making a random number which is within the range of a 32-bit signed int. floor is converting it to an actual int, then toString(36) is converting it to a 36-character alphabet, which is 0-9 (10 characters) plus a-z (26 characters).
The end-result of that first line is a string of random numbers and letters. There will be 6 of them (36^6 = 2176782336), but the first one won't be quite as random as the others (won't be late in the alphabet). Edit: Adrian has worked this out properly in his answer; the first letter can be any of the 36 characters, but is slightly less likely to be Z. The other letters have a small bias towards lower values.
For question 2, if you mean this a = String(a); then yes, it is ensuring that a is a string. This is also a hint to the compiler so that it can make better optimisations if it's able to convert it to machine code (I don't know if they can for strings though).
Edit: OK you clarified the question. f.test(a) && (...) is a common trick which uses short-circuit evaluation. It's effectively saying if(f.test(a)){...}. Don't use it like that in real code because it makes it less readable (although in some cases it is more readable). If you're wondering about test, it's to do with regular expressions.
For question 3, it's new to me too! But see here: What does `void 0` mean? (quick google search. Turns out it's interesting, but weird)
There's a number of different questions rolled into one, but considering the question title I'll just focus on the first here:
Math.floor(Math.random() * 2147483648).toString(36);
In actual fact, this doesn't do anything - as the value is discarded rather than assigned. However, the idea of this is to generate a number between 0 and 2 ^ 31 - 1 and return it in base 36.
Math.random() returns a number from 0 (inclusive) to 1 (exclusive). It is then multipled by 2^31 to produce the range mentioned. The .toString(36) then converts it to base 36, represented by 0 to 9 followed by A to Z.
The end result ranges from 0 to (I believe) ZIK0ZI.
As to why it's there in the first place ... well, examine the slide. This line appears right at the top. Although this is pure conjecture, I actually suspect that the code was cropped down to what's visible, and there was something immediately above it that this was assigned to.
This may be very convoluted and twisted idea. Got it while learning some JavaScript. It piqued my mind. Hoping there may be someone else who would have thought about it before or might enlighten me :-)
var n = 17;
binary_string = n.toString(2); // Evaluates to "10001"
octal_string = "0" + n.toString(8); // Evaluates to "021"
hex_string = "0x" + n.toString(16); // Evaluates to "0x11"
This made me probe more into bases. I remembered my Digital Engineering course and understood that for every number from 10 for a base greater than 10 will be started naming from 'a', 'b' onwards.
for eg:
var n = 10;
var y = 11;
string = n.toString(12); // Evaluates to 'a'
string = y.toString(12); // Evaluates to 'b'
Then I understood this could go uptil 'z'
Thus
var n = 35;
string = n.toString(36); // Evaluates to "z"
But that seems to be the end. if we do
var n = 35;
string = n.toString(37); // Gives error Error: illegal radix 37 { message="illegal radix 37", more...}
Thus I believe we can only count up to the bases of 36. since for a base 37 counting system, we wont be able to count 36 since we exhausted English characters. Is there anyway we can do it? Maybe we can add other characters.
I know it is very useless thing, and never in life will we ever need it.
But have anyone thought about it already?
see my question here. What symbols are used after base 36
Yes, of course it can be done, just not with JavaScript's toString function.
You just need to decide on which characters to use for your digits. This is largely arbitrary, although there are some established standards. See, for example, Base64, Ascii85 etc.
You can certainly do it, number bases are complete arbitrary (using the English alphabet after 9 is just a common convention). Number#toString is specifically designed to handle base 2 through 36:
The optional radix should be an integer value in the inclusive range 2 to 36.
From the spec, section 15.7.4.2.
In some code I'm working on I should take care of ten independent parameters which can take one of two values (0 or 1). This creates 2^10 distinct conditions. Some of the conditions never occur and can be left out, but those which do occur are still A LOT and making a switch to handle all cases is insane.
I want to use 10 if statements instead of a huge switch. For this I know I should use flag bits, or rather flag bytes as the language is javascript and its easier to work with a 10 byte string with to represent a 10-bit binary.
Now, my problem is, I don't know how to implement this. I have seen this used in APIs where multiple-selectable options are exposed with numbers 1, 2, 4, 8, ... , n^(n-1) which are decimal equivalents of 1, 10, 100, 1000, etc. in binary. So if we make call like bar = foo(7), bar will be an object with whatever options the three rightmost flags enable.
I can convert the decimal number into binary and in each if statement check to see if the corresponding digit is set or not. But I wonder, is there a way to determine the n-th digit of a decimal number is zero or one in binary form, without actually doing the conversion?
Just use a bitwise-and. In C/C++, this would be:
if (flags & 1) {
// Bit zero is set.
}
if (flags & 2) {
// Bit one is set.
}
if (flags & 4) {
// Bit two is set.
}
...
For production goodness, use symbolic names for the flag masks instead of the magic numbers, 1, 2, 4, 8, etc.
If the flags are homogeneous in some way (e.g., they represent ten spatial dimensions in some geometry problem) and the code to handle each case is the same, you can use a loop:
for (int f = 0; f < 10; ++f) {
if (flags & (1 << f)) {
// Bit f is set.
}
}
You can use a bitwise and:
10 & 2^1 is true because 10 = 1010b
^ 1
8 & 2^1 is false because 8 = 1000b
^ 0
10 & 2^3 is true because 10 = 1010b
^ 1
You could get a number that has the n-th bit set and AND it with your number. If the result is zero your number didn't have the bit set. Otherwise, it did. Look here, also.