Why use an anonymous function as a variable? [duplicate] - php

For a person without a comp-sci background, what is a lambda in the world of Computer Science?

Lambda comes from the Lambda Calculus and refers to anonymous functions in programming.
Why is this cool? It allows you to write quick throw away functions without naming them. It also provides a nice way to write closures. With that power you can do things like this.
Python
def adder(x):
return lambda y: x + y
add5 = adder(5)
add5(1)
6
As you can see from the snippet of Python, the function adder takes in an argument x, and returns an anonymous function, or lambda, that takes another argument y. That anonymous function allows you to create functions from functions. This is a simple example, but it should convey the power lambdas and closures have.
Examples in other languages
Perl 5
sub adder {
my ($x) = #_;
return sub {
my ($y) = #_;
$x + $y
}
}
my $add5 = adder(5);
print &$add5(1) == 6 ? "ok\n" : "not ok\n";
JavaScript
var adder = function (x) {
return function (y) {
return x + y;
};
};
add5 = adder(5);
add5(1) == 6
JavaScript (ES6)
const adder = x => y => x + y;
add5 = adder(5);
add5(1) == 6
Scheme
(define adder
(lambda (x)
(lambda (y)
(+ x y))))
(define add5
(adder 5))
(add5 1)
6
C# 3.5 or higher
Func<int, Func<int, int>> adder =
(int x) => (int y) => x + y; // `int` declarations optional
Func<int, int> add5 = adder(5);
var add6 = adder(6); // Using implicit typing
Debug.Assert(add5(1) == 6);
Debug.Assert(add6(-1) == 5);
// Closure example
int yEnclosed = 1;
Func<int, int> addWithClosure =
(x) => x + yEnclosed;
Debug.Assert(addWithClosure(2) == 3);
Swift
func adder(x: Int) -> (Int) -> Int{
return { y in x + y }
}
let add5 = adder(5)
add5(1)
6
PHP
$a = 1;
$b = 2;
$lambda = fn () => $a + $b;
echo $lambda();
Haskell
(\x y -> x + y)
Java see this post
// The following is an example of Predicate :
// a functional interface that takes an argument
// and returns a boolean primitive type.
Predicate<Integer> pred = x -> x % 2 == 0; // Tests if the parameter is even.
boolean result = pred.test(4); // true
Lua
adder = function(x)
return function(y)
return x + y
end
end
add5 = adder(5)
add5(1) == 6 -- true
Kotlin
val pred = { x: Int -> x % 2 == 0 }
val result = pred(4) // true
Ruby
Ruby is slightly different in that you cannot call a lambda using the exact same syntax as calling a function, but it still has lambdas.
def adder(x)
lambda { |y| x + y }
end
add5 = adder(5)
add5[1] == 6
Ruby being Ruby, there is a shorthand for lambdas, so you can define adder this way:
def adder(x)
-> y { x + y }
end
R
adder <- function(x) {
function(y) x + y
}
add5 <- adder(5)
add5(1)
#> [1] 6

A lambda is a type of function, defined inline. Along with a lambda you also usually have some kind of variable type that can hold a reference to a function, lambda or otherwise.
For instance, here's a C# piece of code that doesn't use a lambda:
public Int32 Add(Int32 a, Int32 b)
{
return a + b;
}
public Int32 Sub(Int32 a, Int32 b)
{
return a - b;
}
public delegate Int32 Op(Int32 a, Int32 b);
public void Calculator(Int32 a, Int32 b, Op op)
{
Console.WriteLine("Calculator: op(" + a + ", " + b + ") = " + op(a, b));
}
public void Test()
{
Calculator(10, 23, Add);
Calculator(10, 23, Sub);
}
This calls Calculator, passing along not just two numbers, but which method to call inside Calculator to obtain the results of the calculation.
In C# 2.0 we got anonymous methods, which shortens the above code to:
public delegate Int32 Op(Int32 a, Int32 b);
public void Calculator(Int32 a, Int32 b, Op op)
{
Console.WriteLine("Calculator: op(" + a + ", " + b + ") = " + op(a, b));
}
public void Test()
{
Calculator(10, 23, delegate(Int32 a, Int32 b)
{
return a + b;
});
Calculator(10, 23, delegate(Int32 a, Int32 b)
{
return a - b;
});
}
And then in C# 3.0 we got lambdas which makes the code even shorter:
public delegate Int32 Op(Int32 a, Int32 b);
public void Calculator(Int32 a, Int32 b, Op op)
{
Console.WriteLine("Calculator: op(" + a + ", " + b + ") = " + op(a, b));
}
public void Test()
{
Calculator(10, 23, (a, b) => a + b);
Calculator(10, 23, (a, b) => a - b);
}

The name "lambda" is just a historical artifact. All we're talking about is an expression whose value is a function.
A simple example (using Scala for the next line) is:
args.foreach(arg => println(arg))
where the argument to the foreach method is an expression for an anonymous function. The above line is more or less the same as writing something like this (not quite real code, but you'll get the idea):
void printThat(Object that) {
println(that)
}
...
args.foreach(printThat)
except that you don't need to bother with:
Declaring the function somewhere else (and having to look for it when you revisit the code later).
Naming something that you're only using once.
Once you're used to function values, having to do without them seems as silly as being required to name every expression, such as:
int tempVar = 2 * a + b
...
println(tempVar)
instead of just writing the expression where you need it:
println(2 * a + b)
The exact notation varies from language to language; Greek isn't always required! ;-)

It refers to lambda calculus, which is a formal system that just has lambda expressions, which represent a function that takes a function for its sole argument and returns a function. All functions in the lambda calculus are of that type, i.e., λ : λ → λ.
Lisp used the lambda concept to name its anonymous function literals. This lambda represents a function that takes two arguments, x and y, and returns their product:
(lambda (x y) (* x y))
It can be applied in-line like this (evaluates to 50):
((lambda (x y) (* x y)) 5 10)

The lambda calculus is a consistent mathematical theory of substitution. In school mathematics one sees for example x+y=5 paired with x−y=1. Along with ways to manipulate individual equations it's also possible to put the information from these two together, provided cross-equation substitutions are done logically. Lambda calculus codifies the correct way to do these substitutions.
Given that y = x−1 is a valid rearrangement of the second equation, this: λ y = x−1 means a function substituting the symbols x−1 for the symbol y. Now imagine applying λ y to each term in the first equation. If a term is y then perform the substitution; otherwise do nothing. If you do this out on paper you'll see how applying that λ y will make the first equation solvable.
That's an answer without any computer science or programming.
The simplest programming example I can think of comes from http://en.wikipedia.org/wiki/Joy_(programming_language)#How_it_works:
here is how the square function might be defined in an imperative
programming language (C):
int square(int x)
{
return x * x;
}
The variable x is a formal parameter which is replaced by the actual
value to be squared when the function is called. In a functional
language (Scheme) the same function would be defined:
(define square
(lambda (x)
(* x x)))
This is different in many ways, but it still uses the formal parameter
x in the same way.
Added: http://imgur.com/a/XBHub

Slightly oversimplified: a lambda function is one that can be passed round to other functions and it's logic accessed.
In C# lambda syntax is often compiled to simple methods in the same way as anonymous delegates, but it can also be broken down and its logic read.
For instance (in C#3):
LinqToSqlContext.Where(
row => row.FieldName > 15 );
LinqToSql can read that function (x > 15) and convert it to the actual SQL to execute using expression trees.
The statement above becomes:
select ... from [tablename]
where [FieldName] > 15 --this line was 'read' from the lambda function
This is different from normal methods or anonymous delegates (which are just compiler magic really) because they cannot be read.
Not all methods in C# that use lambda syntax can be compiled to expression trees (i.e. actual lambda functions). For instance:
LinqToSqlContext.Where(
row => SomeComplexCheck( row.FieldName ) );
Now the expression tree cannot be read - SomeComplexCheck cannot be broken down. The SQL statement will execute without the where, and every row in the data will be put through SomeComplexCheck.
Lambda functions should not be confused with anonymous methods. For instance:
LinqToSqlContext.Where(
delegate ( DataRow row ) {
return row.FieldName > 15;
} );
This also has an 'inline' function, but this time it's just compiler magic - the C# compiler will split this out to a new instance method with an autogenerated name.
Anonymous methods can't be read, and so the logic can't be translated out as it can for lambda functions.

The question is formally answered greatly, so I will not try to add more on this.
In very simple, informal words to someone that knows very little or nothing on math or programming, I would explain it as a small "machine" or "box" that takes some input, makes some work and produces some output, has no particular name, but we know where it is and by just this knowledge, we use it.
Practically speaking, for a person that knows what a function is, I would tell them that it is a function that has no name, usually put to a point in memory that can be used just by referencing to that memory (usually via the usage of a variable - if they have heard about the concept of the function pointers, I would use them as a similar concept) - this answer covers the pretty basics (no mention of closures etc) but one can get the point easily.

I like the explanation of Lambdas in this article: The Evolution Of LINQ And Its Impact On The Design Of C#. It made a lot of sense to me as it shows a real world for Lambdas and builds it out as a practical example.
Their quick explanation: Lambdas are a way to treat code (functions) as data.

A Lambda Function, or a Small Anonymous Function, is a self-contained block of functionality that can be passed around and used in your code. Lambda has different names in different programming languages – Lambda in Python and Kotlin, Closure in Swift, or Block in C and Objective-C. Although lambda's meaning is quite similar for these languages it has slight distinctions sometimes.
Let's see how Closure (Lambda) works in Swift:
let coffee: [String] = ["Cappuccino", "Espresso", "Latte", "Ristretto"]
1. Regular Function
func backward(_ n1: String, _ n2: String) -> Bool {
return n1 > n2
}
var reverseOrder = coffee.sorted(by: backward)
// RESULT: ["Ristretto", "Latte", "Espresso", "Cappuccino"]
2. Closure Expression
reverseOrder = coffee.sorted(by: { (n1: String, n2: String) -> Bool in
return n1 > n2
})
3. Inline Closure Expression
reverseOrder = coffee.sorted(by: { (n1: String, n2: String) -> Bool in
return n1 > n2
})
4. Inferring Type From Context
reverseOrder = coffee.sorted(by: { n1, n2 in return n1 > n2 } )
5. Implicit Returns from Single-Expression Closures
reverseOrder = coffee.sorted(by: { n1, n2 in n1 > n2 } )
6. Shorthand Argument Names
reverseOrder = coffee.sorted(by: { $0 > $1 } )
// $0 and $1 are closure’s first and second String arguments.
7. Operator Methods
reverseOrder = coffee.sorted(by: >)
// RESULT: ["Ristretto", "Latte", "Espresso", "Cappuccino"]

#Brian I use lambdas all the time in C#, in LINQ and non-LINQ operators. Example:
string[] GetCustomerNames(IEnumerable<Customer> customers)
{ return customers.Select(c=>c.Name);
}
Before C#, I used anonymous functions in JavaScript for callbacks to AJAX functions, before the term Ajax was even coined:
getXmlFromServer(function(result) {/*success*/}, function(error){/*fail*/});
The interesting thing with C#'s lambda syntax, though, is that on their own their type cannot be infered (i.e., you can't type var foo = (x,y) => x * y) but depending on which type they're assigned to, they'll be compiled as delegates or abstract syntax trees representing the expression (which is how LINQ object mappers do their "language-integrated" magic).
Lambdas in LISP can also be passed to a quotation operator and then traversed as a list of lists. Some powerful macros are made this way.

An example of a lambda in Ruby is as follows:
hello = lambda do
puts('Hello')
puts('I am inside a proc')
end
hello.call
Will genereate the following output:
Hello
I am inside a proc

Just because I cant see a C++11 example here, I'll go ahead and post this nice example from here. After searching, it is the clearest language specific example that I could find.
Hello, Lambdas, version 1
template<typename F>
void Eval( const F& f ) {
    f();
}
void foo() {
    Eval( []{ printf("Hello, Lambdas\n"); } );
}
Hello, Lambdas, version 2:
void bar() {
    auto f = []{ printf("Hello, Lambdas\n"); };
    f();
}

For a person without a comp-sci background, what is a lambda in the world of Computer Science?
I will illustrate it intuitively step by step in simple and readable python codes.
In short, a lambda is just an anonymous and inline function.
Let's start from assignment to understand lambdas as a freshman with background of basic arithmetic.
The blueprint of assignment is 'the name = value', see:
In [1]: x = 1
...: y = 'value'
In [2]: x
Out[2]: 1
In [3]: y
Out[3]: 'value'
'x', 'y' are names and 1, 'value' are values.
Try a function in mathematics
In [4]: m = n**2 + 2*n + 1
NameError: name 'n' is not defined
Error reports,
you cannot write a mathematic directly as code,'n' should be defined or be assigned to a value.
In [8]: n = 3.14
In [9]: m = n**2 + 2*n + 1
In [10]: m
Out[10]: 17.1396
It works now,what if you insist on combining the two seperarte lines to one.
There comes lambda
In [13]: j = lambda i: i**2 + 2*i + 1
In [14]: j
Out[14]: <function __main__.<lambda>>
No errors reported.
This is a glance at lambda, it enables you to write a function in a single line as you do in mathematic into the computer directly.
We will see it later.
Let's continue on digging deeper on 'assignment'.
As illustrated above, the equals symbol = works for simple data(1 and 'value') type and simple expression(n**2 + 2*n + 1).
Try this:
In [15]: x = print('This is a x')
This is a x
In [16]: x
In [17]: x = input('Enter a x: ')
Enter a x: x
It works for simple statements,there's 11 types of them in python 7. Simple statements — Python 3.6.3 documentation
How about compound statement,
In [18]: m = n**2 + 2*n + 1 if n > 0
SyntaxError: invalid syntax
#or
In [19]: m = n**2 + 2*n + 1, if n > 0
SyntaxError: invalid syntax
There comes def enable it working
In [23]: def m(n):
...: if n > 0:
...: return n**2 + 2*n + 1
...:
In [24]: m(2)
Out[24]: 9
Tada, analyse it, 'm' is name, 'n**2 + 2*n + 1' is value.: is a variant of '='.
Find it, if just for understanding, everything starts from assignment and everything is assignment.
Now return to lambda, we have a function named 'm'
Try:
In [28]: m = m(3)
In [29]: m
Out[29]: 16
There are two names of 'm' here, function m already has a name, duplicated.
It's formatting like:
In [27]: m = def m(n):
...: if n > 0:
...: return n**2 + 2*n + 1
SyntaxError: invalid syntax
It's not a smart strategy, so error reports
We have to delete one of them,set a function without a name.
m = lambda n:n**2 + 2*n + 1
It's called 'anonymous function'
In conclusion,
lambda in an inline function which enable you to write a function in one straight line as does in mathematics
lambda is anonymous
Hope, this helps.

Lambda explained for everyone:
Lambda is an anonymous function. This means lambda is a function object in Python that doesn't require a reference before. Let's consider this bit of code here:
def name_of_func():
#command/instruction
print('hello')
print(type(name_of_func)) #the name of the function is a reference
#the reference contains a function Object with command/instruction
To proof my proposition I print out the type of name_of_func which returns us:
<class 'function'>
A function must have a interface, but a interface docent needs to contain something. What does this mean? Let's look a little bit closer to our function and we may notice that out of the name of the functions there are some more details we need to explain to understand what a function is.
A regular function will be defined with the syntax "def", then we type in the name and settle the interface with "()" and ending our definition by the syntax ":". Now we enter the functions body with our instructions/commands.
So let's consider this bit of code here:
def print_my_argument(x):
print(x)
print_my_argument('Hello')
In this case we run our function, named "print_my_argument" and passing a parameter/argument through the interface. The Output will be:
Hello
So now that we know what a function is and how the architecture works for a function, we can take a look to an anonymous function. Let's consider this bit of code here:
def name_of_func():
print('Hello')
lambda: print('Hello')
these function objects are pretty much the same except of the fact that the upper, regular function have a name and the other function is an anonymous one. Let's take a closer look on our anonymous function, to understand how to use it.
So let's consider this bit of code here:
def delete_last_char(arg1=None):
print(arg1[:-1])
string = 'Hello World'
delete_last_char(string)
f = lambda arg1=None: print(arg1[:-1])
f(string)
So what we have done in the above code is to write once again, a regular function and an anonymous function. Our anonymous function we had assigned to a var, which is pretty much the same as to give this function a name. Anyway, the output will be:
Hello Worl
Hello Worl
To fully proof that lambda is a function object and doesn't just mimic a function we run this bit of code here:
string = 'Hello World'
f = lambda arg1=string: print(arg1[:-1])
f()
print(type(f))
and the Output will be:
Hello Worl
<class 'function'>
Last but not least you should know that every function in python needs to return something. If nothing is defined in the body of the function, None will be returned by default. look at this bit of code here:
def delete_last_char(arg1):
print(arg1[:-1])
string = 'Hello World'
x = delete_last_char(string)
f = lambda arg1=string: print(arg1[:-1])
x2 = f()
print(x)
print(x2)
Output will be:
Hello Worl
Hello Worl
None
None

You can think of it as an anonymous function - here's some more info: Wikipedia - Anonymous Function

I have trouble wrapping my head around lambda expressions because I work in Visual FoxPro, which has Macro substitution and the ExecScript{} and Evaluate() functions, which seem to serve much the same purpose.
? Calculator(10, 23, "a + b")
? Calculator(10, 23, "a - b");
FUNCTION Calculator(a, b, op)
RETURN Evaluate(op)
One definite benefit to using formal lambdas is (I assume) compile-time checking: Fox won't know if you typo the text string above until it tries to run it.
This is also useful for data-driven code: you can store entire routines in memo fields in the database and then just evaluate them at run-time. This lets you tweak part of the application without actually having access to the source. (But that's another topic altogether.)

It is a function that has no name. For e.g. in c# you can use
numberCollection.GetMatchingItems<int>(number => number > 5);
to return the numbers that are greater than 5.
number => number > 5
is the lambda part here. It represents a function which takes a parameter (number) and returns a boolean value (number > 5). GetMatchingItems method uses this lambda on all the items in the collection and returns the matching items.

In Javascript, for example, functions are treated as the same mixed type as everything else (int, string, float, bool). As such, you can create functions on the fly, assign them to things, and call them back later. It's useful but, not something you want to over use or you'll confuse everyone who has to maintain your code after you...
This is some code I was playing with to see how deep this rabbit hole goes:
var x = new Object;
x.thingy = new Array();
x.thingy[0] = function(){ return function(){ return function(){ alert('index 0 pressed'); }; }; }
x.thingy[1] = function(){ return function(){ return function(){ alert('index 1 pressed'); }; }; }
x.thingy[2] = function(){ return function(){ return function(){ alert('index 2 pressed'); }; }; }
for(var i=0 ;i<3; i++)
x.thingy[i]()()();

In context of CS a lambda function is an abstract mathematical concept that tackles a problem of symbolic evaluation of mathematical expressions. In that context a lambda function is the same as a lambda term.
But in programming languages it's something different. It's a piece of code that is declared "in place", and that can be passed around as a "first-class citizen". This concept appeared to be useful so that it came into almost all popular modern programming languages (see lambda functions everwhere post).

In computer programming, lambda is a piece of code (statement, expression or a group of them) which takes some arguments from an external source. It must not always be an anonymous function - we have many ways to implement them.
We have clear separation between expressions, statements and functions, which mathematicians do not have.
The word "function" in programming is also different - we have "function is a series of steps to do" (from Latin "perform"). In math it is something about correlation between variables.
Functional languages are trying to be as similar to math formulas as possible, and their words mean almost the same. But in other programming languages we have it different.

The question has been answered fully, I don't want to go into details. I want to share the usage when writing numerical computation in rust.
There is an example of a lambda(anonymous function)
let f = |x: f32| -> f32 { x * x - 2.0 };
let df = |x: f32| -> f32 { 2.0 * x };
When I was writing a module of Newton–Raphson method, it was used as first and second order derivative. (If you want to know what is Newton–Raphson method, please visit "https://en.wikipedia.org/wiki/Newton%27s_method".
The output as the following
println!("f={:.6} df={:.6}", f(10.0), df(10.0))
f=98.000000 df=20.000000

Imagine that you have a restaurant with a delivery option and you have an order that needs to be done in under 30 minutes. The point is clients usually don't care if you send their food by bike with a car or barefoot as long as you keep the meal warm and tied up. So lets convert this idiom to Javascript with anonymous and defined transportation functions.
Below we defined the way of our delivering aka we define a name to a function:
// ES5
var food = function withBike(kebap, coke) {
return (kebap + coke);
};
What if we would use arrow/lambda functions to accomplish this transfer:
// ES6
const food = (kebap, coke) => { return kebap + coke };
You see there is no difference for client and no time wasting to think about how to send food. Just send it.
Btw, I don't recommend the kebap with coke this is why upper codes will give you errors. Have fun.

A lambda function can take any number of arguments, but they contain only a single expression. ...
Lambda functions can be used to return function objects.
Syntactically, lambda functions are restricted to only a single expression.

Related

how to output INT values with proper commas from a mysql table? [duplicate]

I am trying to print an integer in JavaScript with commas as thousands separators. For example, I want to show the number 1234567 as "1,234,567". How would I go about doing this?
Here is how I am doing it:
function numberWithCommas(x) {
x = x.toString();
var pattern = /(-?\d+)(\d{3})/;
while (pattern.test(x))
x = x.replace(pattern, "$1,$2");
return x;
}
console.log(numberWithCommas(1000))
Is there a simpler or more elegant way to do it? It would be nice if it works with floats also, but that is not necessary. It does not need to be locale-specific to decide between periods and commas.
I used the idea from Kerry's answer, but simplified it since I was just looking for something simple for my specific purpose. Here is what I have:
function numberWithCommas(x) {
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
function numberWithCommas(x) {
return x.toString().replace(/\B(?<!\.\d*)(?=(\d{3})+(?!\d))/g, ",");
}
function test(x, expect) {
const result = numberWithCommas(x);
const pass = result === expect;
console.log(`${pass ? "✓" : "ERROR ====>"} ${x} => ${result}`);
return pass;
}
let failures = 0;
failures += !test(0, "0");
failures += !test(100, "100");
failures += !test(1000, "1,000");
failures += !test(10000, "10,000");
failures += !test(100000, "100,000");
failures += !test(1000000, "1,000,000");
failures += !test(10000000, "10,000,000");
if (failures) {
console.log(`${failures} test(s) failed`);
} else {
console.log("All tests passed");
}
.as-console-wrapper {
max-height: 100% !important;
}
The regex uses 2 lookahead assertions:
a positive one to look for any point in the string that has a multiple of 3 digits in a row after it,
a negative assertion to make sure that point only has exactly a multiple of 3 digits. The replacement expression puts a comma there.
For example, if you pass it 123456789.01, the positive assertion will match every spot to the left of the 7 (since 789 is a multiple of 3 digits, 678 is a multiple of 3 digits, 567, etc.). The negative assertion checks that the multiple of 3 digits does not have any digits after it. 789 has a period after it so it is exactly a multiple of 3 digits, so a comma goes there. 678 is a multiple of 3 digits but it has a 9 after it, so those 3 digits are part of a group of 4, and a comma does not go there. Similarly for 567. 456789 is 6 digits, which is a multiple of 3, so a comma goes before that. 345678 is a multiple of 3, but it has a 9 after it, so no comma goes there. And so on. The \B keeps the regex from putting a comma at the beginning of the string.
#neu-rah mentioned that this function adds commas in undesirable places if there are more than 3 digits after the decimal point. If this is a problem, you can use this function:
function numberWithCommas(x) {
var parts = x.toString().split(".");
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
return parts.join(".");
}
function numberWithCommas(x) {
var parts = x.toString().split(".");
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
return parts.join(".");
}
function test(x, expect) {
const result = numberWithCommas(x);
const pass = result === expect;
console.log(`${pass ? "✓" : "ERROR ====>"} ${x} => ${result}`);
return pass;
}
let failures = 0;
failures += !test(0 , "0");
failures += !test(0.123456 , "0.123456");
failures += !test(100 , "100");
failures += !test(100.123456 , "100.123456");
failures += !test(1000 , "1,000");
failures += !test(1000.123456 , "1,000.123456");
failures += !test(10000 , "10,000");
failures += !test(10000.123456 , "10,000.123456");
failures += !test(100000 , "100,000");
failures += !test(100000.123456 , "100,000.123456");
failures += !test(1000000 , "1,000,000");
failures += !test(1000000.123456 , "1,000,000.123456");
failures += !test(10000000 , "10,000,000");
failures += !test(10000000.123456, "10,000,000.123456");
if (failures) {
console.log(`${failures} test(s) failed`);
} else {
console.log("All tests passed");
}
.as-console-wrapper {
max-height: 100% !important;
}
#t.j.crowder pointed out that now that JavaScript has lookbehind (support info), it can be solved in the regular expression itself:
function numberWithCommas(x) {
return x.toString().replace(/\B(?<!\.\d*)(?=(\d{3})+(?!\d))/g, ",");
}
function numberWithCommas(x) {
return x.toString().replace(/\B(?<!\.\d*)(?=(\d{3})+(?!\d))/g, ",");
}
function test(x, expect) {
const result = numberWithCommas(x);
const pass = result === expect;
console.log(`${pass ? "✓" : "ERROR ====>"} ${x} => ${result}`);
return pass;
}
let failures = 0;
failures += !test(0, "0");
failures += !test(0.123456, "0.123456");
failures += !test(100, "100");
failures += !test(100.123456, "100.123456");
failures += !test(1000, "1,000");
failures += !test(1000.123456, "1,000.123456");
failures += !test(10000, "10,000");
failures += !test(10000.123456, "10,000.123456");
failures += !test(100000, "100,000");
failures += !test(100000.123456, "100,000.123456");
failures += !test(1000000, "1,000,000");
failures += !test(1000000.123456, "1,000,000.123456");
failures += !test(10000000, "10,000,000");
failures += !test(10000000.123456, "10,000,000.123456");
if (failures) {
console.log(`${failures} test(s) failed`);
} else {
console.log("All tests passed");
}
.as-console-wrapper {
max-height: 100% !important;
}
(?<!\.\d*) is a negative lookbehind that says the match can't be preceded by a . followed by zero or more digits. The negative lookbehind is faster than the split and join solution (comparison), at least in V8.
I'm surprised nobody mentioned Number.prototype.toLocaleString.
It's implemented in JavaScript 1.5 (which was introduced in 1999) so it's basically supported across all major browsers.
var n = 34523453.345;
console.log(n.toLocaleString()); // "34,523,453.345"
It also works in Node.js as of v0.12 via inclusion of Intl
If you want something different, Numeral.js might be interesting.
Below are two different browser APIs that can transform Numbers into structured Strings. Keep in mind that not all users' machines have a locale that uses commas in numbers. To enforce commas to the output, any "western" locale may be used, such as en-US
let number = 1234567890; // Example number to be converted
⚠️ Mind that javascript has a maximum integer value of 9007199254740991
toLocaleString
// default behaviour on a machine with a local that uses commas for numbers
let number = 1234567890;
number.toLocaleString(); // "1,234,567,890"
// With custom settings, forcing a "US" locale to guarantee commas in output
let number2 = 1234.56789; // floating point example
number2.toLocaleString('en-US', {maximumFractionDigits:2}); // "1,234.57"
//You can also force a minimum of 2 trailing digits
let number3 = 1.5;
number3.toLocaleString('en-US', {minimumFractionDigits:2, maximumFractionDigits:2}); //"1.50"
NumberFormat
let number = 1234567890;
let nf = new Intl.NumberFormat('en-US');
nf.format(number); // "1,234,567,890"
From what I checked (Firefox at least) they are both more or less same regarding performance.
⚡ Live demo: https://codepen.io/vsync/pen/MWjdbgL?editors=1000
I suggest using phpjs.org 's number_format()
function number_format(number, decimals, dec_point, thousands_sep) {
var n = !isFinite(+number) ? 0 : +number,
prec = !isFinite(+decimals) ? 0 : Math.abs(decimals),
sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep,
dec = (typeof dec_point === 'undefined') ? '.' : dec_point,
toFixedFix = function (n, prec) {
// Fix for IE parseFloat(0.55).toFixed(0) = 0;
var k = Math.pow(10, prec);
return Math.round(n * k) / k;
},
s = (prec ? toFixedFix(n, prec) : Math.round(n)).toString().split('.');
if (s[0].length > 3) {
s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep);
}
if ((s[1] || '').length < prec) {
s[1] = s[1] || '';
s[1] += new Array(prec - s[1].length + 1).join('0');
}
return s.join(dec);
}
UPDATE 02/13/14
People have been reporting this doesn't work as expected, so I did a JS Fiddle that includes automated tests.
Update 26/11/2017
Here's that fiddle as a Stack Snippet with slightly modified output:
function number_format(number, decimals, dec_point, thousands_sep) {
var n = !isFinite(+number) ? 0 : +number,
prec = !isFinite(+decimals) ? 0 : Math.abs(decimals),
sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep,
dec = (typeof dec_point === 'undefined') ? '.' : dec_point,
toFixedFix = function (n, prec) {
// Fix for IE parseFloat(0.55).toFixed(0) = 0;
var k = Math.pow(10, prec);
return Math.round(n * k) / k;
},
s = (prec ? toFixedFix(n, prec) : Math.round(n)).toString().split('.');
if (s[0].length > 3) {
s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep);
}
if ((s[1] || '').length < prec) {
s[1] = s[1] || '';
s[1] += new Array(prec - s[1].length + 1).join('0');
}
return s.join(dec);
}
var exampleNumber = 1;
function test(expected, number, decimals, dec_point, thousands_sep)
{
var actual = number_format(number, decimals, dec_point, thousands_sep);
console.log(
'Test case ' + exampleNumber + ': ' +
'(decimals: ' + (typeof decimals === 'undefined' ? '(default)' : decimals) +
', dec_point: "' + (typeof dec_point === 'undefined' ? '(default)' : dec_point) + '"' +
', thousands_sep: "' + (typeof thousands_sep === 'undefined' ? '(default)' : thousands_sep) + '")'
);
console.log(' => ' + (actual === expected ? 'Passed' : 'FAILED') + ', got "' + actual + '", expected "' + expected + '".');
exampleNumber++;
}
test('1,235', 1234.56);
test('1 234,56', 1234.56, 2, ',', ' ');
test('1234.57', 1234.5678, 2, '.', '');
test('67,00', 67, 2, ',', '.');
test('1,000', 1000);
test('67.31', 67.311, 2);
test('1,000.6', 1000.55, 1);
test('67.000,00000', 67000, 5, ',', '.');
test('1', 0.9, 0);
test('1.20', '1.20', 2);
test('1.2000', '1.20', 4);
test('1.200', '1.2000', 3);
.as-console-wrapper {
max-height: 100% !important;
}
This is a variation of #mikez302's answer, but modified to support numbers with decimals (per #neu-rah's feedback that numberWithCommas(12345.6789) -> "12,345.6,789" instead of "12,345.6789"
function numberWithCommas(n) {
var parts=n.toString().split(".");
return parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",") + (parts[1] ? "." + parts[1] : "");
}
function formatNumber (num) {
return num.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,")
}
print(formatNumber(2665)); // 2,665
print(formatNumber(102665)); // 102,665
print(formatNumber(111102665)); // 111,102,665
Using Regular expression
function toCommas(value) {
return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
console.log(toCommas(123456789)); // 123,456,789
console.log(toCommas(1234567890)); // 1,234,567,890
console.log(toCommas(1234)); // 1,234
Using toLocaleString()
var number = 123456.789;
// request a currency format
console.log(number.toLocaleString('de-DE', { style: 'currency', currency: 'EUR' }));
// → 123.456,79 €
// the Japanese yen doesn't use a minor unit
console.log(number.toLocaleString('ja-JP', { style: 'currency', currency: 'JPY' }))
// → ¥123,457
// limit to three significant digits
console.log(number.toLocaleString('en-IN', { maximumSignificantDigits: 3 }));
// → 1,23,000
ref MDN:Number.prototype.toLocaleString()
Using Intl.NumberFormat()
var number = 123456.789;
console.log(new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(number));
// expected output: "123.456,79 €"
// the Japanese yen doesn't use a minor unit
console.log(new Intl.NumberFormat('ja-JP', { style: 'currency', currency: 'JPY' }).format(number));
// expected output: "¥123,457"
// limit to three significant digits
console.log(new Intl.NumberFormat('en-IN', { maximumSignificantDigits: 3 }).format(number));
// expected output: "1,23,000"
ref Intl.NumberFormat
DEMO AT HERE
<script type="text/javascript">
// Using Regular expression
function toCommas(value) {
return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
function commas() {
var num1 = document.myform.number1.value;
// Using Regular expression
document.getElementById('result1').value = toCommas(parseInt(num1));
// Using toLocaleString()
document.getElementById('result2').value = parseInt(num1).toLocaleString('ja-JP', {
style: 'currency',
currency: 'JPY'
});
// Using Intl.NumberFormat()
document.getElementById('result3').value = new Intl.NumberFormat('ja-JP', {
style: 'currency',
currency: 'JPY'
}).format(num1);
}
</script>
<FORM NAME="myform">
<INPUT TYPE="text" NAME="number1" VALUE="123456789">
<br>
<INPUT TYPE="button" NAME="button" Value="=>" onClick="commas()">
<br>Using Regular expression
<br>
<INPUT TYPE="text" ID="result1" NAME="result1" VALUE="">
<br>Using toLocaleString()
<br>
<INPUT TYPE="text" ID="result2" NAME="result2" VALUE="">
<br>Using Intl.NumberFormat()
<br>
<INPUT TYPE="text" ID="result3" NAME="result3" VALUE="">
</FORM>
Performance
http://jsben.ch/sifRd
Intl.NumberFormat
Native JS function. Supported by IE11, Edge, latest Safari, Chrome, Firefox, Opera, Safari on iOS and Chrome on Android.
var number = 3500;
console.log(new Intl.NumberFormat().format(number));
// → '3,500' if in US English locale
I am quite impressed by the number of answers this question has got. I like the answer by uKolka:
n.toLocaleString()
But unfortunately, in some locales like Spanish, it does not work (IMHO) as expected for numbers below 10,000:
Number(1000).toLocaleString('ES-es')
Gives 1000 and not 1.000.
See toLocaleString not working on numbers less than 10000 in all browsers to know why.
So I had to use the answer by Elias Zamaria choosing the right thousands separator character:
n.toString().replace(/\B(?=(\d{3})+(?!\d))/g, Number(10000).toLocaleString().substring(2, 3))
This one works well as a one-liner for both locales that use , or . as the thousands separator and starts working from 1,000 in all cases.
Number(1000).toString().replace(/\B(?=(\d{3})+(?!\d))/g, Number(10000).toLocaleString().substring(2, 3))
Gives 1.000 with a Spanish locale context.
Should you want to have absolute control over the way a number is formatted, you may also try the following:
let number = 1234.567
let decimals = 2
let decpoint = '.' // Or Number(0.1).toLocaleString().substring(1, 2)
let thousand = ',' // Or Number(10000).toLocaleString().substring(2, 3)
let n = Math.abs(number).toFixed(decimals).split('.')
n[0] = n[0].split('').reverse().map((c, i, a) =>
i > 0 && i < a.length && i % 3 == 0 ? c + thousand : c
).reverse().join('')
let final = (Math.sign(number) < 0 ? '-' : '') + n.join(decpoint)
console.log(final)
Gives 1,234.57.
This one does not need a regular expression. It works by adjusting the number to the desired amount of decimals with toFixed first, then dividing it around the decimal point . if there is one. The left side is then turned into an array of digits which is reversed. Then a thousands separator is added every three digits from the start and the result reversed again. The final result is the union of the two parts. The sign of the input number is removed with Math.abs first and then put back if necessary.
It is not a one-liner but not much longer and easily turned into a function. Variables have been added for clarity, but those may be substituted by their desired values if known in advance. You may use the expressions that use toLocaleString as a way to find out the right characters for the decimal point and the thousands separator for the current locale (bear in mind that those require a more modern Javascript.)
Thanks to everyone for their replies. I have built off of some of the answers to make a more "one-size-fits-all" solution.
The first snippet adds a function that mimics PHP's number_format() to the Number prototype. If I am formatting a number, I usually want decimal places so the function takes in the number of decimal places to show. Some countries use commas as the decimal and decimals as the thousands separator so the function allows these separators to be set.
Number.prototype.numberFormat = function(decimals, dec_point, thousands_sep) {
dec_point = typeof dec_point !== 'undefined' ? dec_point : '.';
thousands_sep = typeof thousands_sep !== 'undefined' ? thousands_sep : ',';
var parts = this.toFixed(decimals).split('.');
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, thousands_sep);
return parts.join(dec_point);
}
You would use this as follows:
var foo = 5000;
console.log(foo.numberFormat(2)); // us format: 5,000.00
console.log(foo.numberFormat(2, ',', '.')); // european format: 5.000,00
I found that I often needed to get the number back for math operations, but parseFloat converts 5,000 to 5, simply taking the first sequence of integer values. So I created my own float conversion function and added it to the String prototype.
String.prototype.getFloat = function(dec_point, thousands_sep) {
dec_point = typeof dec_point !== 'undefined' ? dec_point : '.';
thousands_sep = typeof thousands_sep !== 'undefined' ? thousands_sep : ',';
var parts = this.split(dec_point);
var re = new RegExp("[" + thousands_sep + "]");
parts[0] = parts[0].replace(re, '');
return parseFloat(parts.join(dec_point));
}
Now you can use both functions as follows:
var foo = 5000;
var fooString = foo.numberFormat(2); // The string 5,000.00
var fooFloat = fooString.getFloat(); // The number 5000;
console.log((fooString.getFloat() + 1).numberFormat(2)); // The string 5,001.00
I think this is the shortest regular expression that does it:
/\B(?=(\d{3})+\b)/g
"123456".replace(/\B(?=(\d{3})+\b)/g, ",")
I checked it on a few numbers and it worked.
Number.prototype.toLocaleString() would have been awesome if it was provided natively by all browsers (Safari).
I checked all other answers but noone seemed to polyfill it. Here is a poc towards that, which is actually a combination of first two answers; if toLocaleString works it uses it, if it doesn't it uses a custom function.
var putThousandsSeparators;
putThousandsSeparators = function(value, sep) {
if (sep == null) {
sep = ',';
}
// check if it needs formatting
if (value.toString() === value.toLocaleString()) {
// split decimals
var parts = value.toString().split('.')
// format whole numbers
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, sep);
// put them back together
value = parts[1] ? parts.join('.') : parts[0];
} else {
value = value.toLocaleString();
}
return value;
};
alert(putThousandsSeparators(1234567.890));
The thousands separator can be inserted in an international-friendly manner using the browser's Intl object:
Intl.NumberFormat().format(1234);
// returns "1,234" if the user's locale is en_US, for example
See MDN's article on NumberFormat for more, you can specify locale behavior or default to the user's. This is a little more foolproof because it respects local differences; many countries use periods to separate digits while a comma denotes the decimals.
Intl.NumberFormat isn't available in all browsers yet, but it works in latest Chrome, Opera, & IE. Firefox's next release should support it. Webkit doesn't seem to have a timeline for implementation.
You can either use this procedure to format your currency needing.
var nf = new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
minimumFractionDigits: 2,
maximumFractionDigits: 2
});
nf.format(123456.789); // ‘$123,456.79’
For more info you can access this link.
https://www.justinmccandless.com/post/formatting-currency-in-javascript/
if you are dealing with currency values and formatting a lot then it might be worth to add tiny accounting.js which handles lot of edge cases and localization:
// Default usage:
accounting.formatMoney(12345678); // $12,345,678.00
// European formatting (custom symbol and separators), could also use options object as second param:
accounting.formatMoney(4999.99, "€", 2, ".", ","); // €4.999,99
// Negative values are formatted nicely, too:
accounting.formatMoney(-500000, "£ ", 0); // £ -500,000
// Simple `format` string allows control of symbol position [%v = value, %s = symbol]:
accounting.formatMoney(5318008, { symbol: "GBP", format: "%v %s" }); // 5,318,008.00 GBP
The following code uses char scan, so there's no regex.
function commafy( num){
var parts = (''+(num<0?-num:num)).split("."), s=parts[0], L, i=L= s.length, o='';
while(i--){ o = (i===0?'':((L-i)%3?'':','))
+s.charAt(i) +o }
return (num<0?'-':'') + o + (parts[1] ? '.' + parts[1] : '');
}
It shows promising performance: http://jsperf.com/number-formatting-with-commas/5
2015.4.26: Minor fix to resolve issue when num<0. See https://jsfiddle.net/runsun/p5tqqvs3/
Here's a simple function that inserts commas for thousand separators. It uses array functions rather than a RegEx.
/**
* Format a number as a string with commas separating the thousands.
* #param num - The number to be formatted (e.g. 10000)
* #return A string representing the formatted number (e.g. "10,000")
*/
var formatNumber = function(num) {
var array = num.toString().split('');
var index = -3;
while (array.length + index > 0) {
array.splice(index, 0, ',');
// Decrement by 4 since we just added another unit to the array.
index -= 4;
}
return array.join('');
};
CodeSandbox link with examples: https://codesandbox.io/s/p38k63w0vq
Use This code to handle currency format for india. Country code can be changed to handle other country currency.
let amount =350256.95
var formatter = new Intl.NumberFormat('en-IN', {
minimumFractionDigits: 2,
});
// Use it.
formatter.format(amount);
output:
3,50,256.95
You can also use the Intl.NumberFormat constructor. Here is how you can do it.
resultNumber = new Intl.NumberFormat('en-IN', { maximumSignificantDigits: 3 }).format(yourNumber);
Universal, fast, accurate, simple function
Using RegEx (Fast & Accurate)
Support Numbers(Float/Integer)/String/Multiple numbers in a string
Smart well (Not grouping decimals - Compatible with different types of grouping)
Support all browsers specially 'Safari' & 'IE' & many older browsers
[Optional] Respecting non-English (Persian/Arabic) digits (+ Pre-fix)
TL;DR - Full version function (minified):
// num: Number/s (String/Number),
// sep: Thousands separator (String) - Default: ','
// dec: Decimal separator (String) - Default: '.' (Just one char)
// u: Universal support for languages characters (String - RegEx character set / class) - Example: '[\\d\\u0660-\\u0669\\u06f0-\\u06f9]' (English/Persian/Arabic), Default: '\\d' (English)
function formatNums(num,sep,dec,u){sep=sep||',';u=u||'\\d';if(typeof num!='string'){num=String(num);if(dec&&dec!='.')num=num.replace('.',dec);}return num.replace(RegExp('\\'+(dec||'.')+u+'+|'+u+'(?=(?:'+u+'{3})+(?!'+u+'))','g'),function(a){return a.length==1?a+sep:a})}
text='100000000 English or Persian/Arabic ۱۲۳۴۵۶۷۸۹/٠١٢٣٤٥٦٧٨٩ this is 123123123.123123123 with this -123123 and these 10 100 1000 123123/123123 (2000000) .33333 100.00 or any like 500000Kg';
console.log(formatNums(10000000.0012));
console.log(formatNums(10000000.0012,'.',',')); // German
console.log(formatNums(text,',','.','[\\d\\u0660-\\u0669\\u06f0-\\u06f9]')); // Respect Persian/Arabic digits
<input oninput="document.getElementById('result').textContent=formatNums(this.value)" placeholder="Type a number here">
<div id="result"></div>
Why NOT satisfied with other answers?
Number.prototype.toLocaleString() / Intl.NumberFormat
(Right answer)
If no well arguments, we can't expect same result. Also with arguments options we still can't be sure what can be the result because it will use local settings and possible client modifications effect on it or the browser/device not support it.
>~2016 browsers support and still in 2021 some reports that in some cases like Safari or IE/Edge do not return as expected.
toLocaleString() Work with numbers, Intl.NumberFormat Work with String/Numbers; Strings will be/have to be parsed and also rounded if necessary, so:
If we already have a localized string with non-English digits we have to replace numbers with the English one, then parse it, then use it again with the local options. (If it return what we expect)
Generally while parsing we cant expect not missing decimal zeros or details in big numbers or respecting other languages numeral characters
Decimal / Thousand separator characters can not be customized more than language options, except with post-fixings with replace() + RegEx again. (For example in Persian usually we don't use the suggested Arabic comma and also sometime we use ∕ Fraction/Division slash as decimal separator)
Slow performance in loops
Not so good RegEx ways (Fastest & One-liner ways)
/\B(?=(\d{3})+\b)/ it will group decimals too. // 123,123.123,123 !!!
/(?<!\.\d+)\B(?=(\d{3})+\b)/ used look-behind that not supported well yet. Please check:
https://caniuse.com/js-regexp-lookbehind
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#browser_compatibility
Note: Generally lookbehind can be against of original RegEx structure (because of how the analyzer should work like do not buffer the raw behind as a parser) and actually it can make the performance seriously low (In this case ~30%). I think it pushed inside over the time by requests.
/\B(?=(?=\d*\.)(\d{3})+(?!\d))/ just work with float numbers and ignore integers.
.replace(/(?:[^.\d]|^)\d+/g,function(a){return a.replace(/\B(?=(?:\d{3})+\b)/g,',');}) (My old idea) Using 2 RegEx. First one find the integer parts, second one put separator. Why 2 functions, when it can be mixed?
/(\..*)$|(\d)(?=(\d{3})+(?!\d))/g (Good idea by #djulien - i voted up) but when the RegEx is global, (\..*)$ it can make a mistake even with a space in end.
Also using capturing groups (Example: (\d)) will make the performance low so if it possible, use non-capturing groups (Example: (?:\d)) or if an statement already exist in our function let's mix it.
In this case, not using capturing groups improve performance about ~20% and in case of /\B(?=(\d{3})+\b)/g vs /\B(?=(?:\d{3})+\b)/g, the second one is ~8% faster.
About regex performances:
Note: Sure different methods, browsers, hardware, system status, cases and even changes on ECMAScript will effect on result of checking performance. But some changes logically should effect result and i used this one just as visual example.
Using library's like Numeral.js so much not necessary functions for a simple task.
Heavy code / Not accurate functions that used .split('.') or .toFixed() or Math.floor() ...
Final result:
There is no best of all and it should be chosen based on the need. My priority of sorting;
Compatibility
Capability
Universality
Ease of use
Performance
toLocaleString() (Compatibility - Universality) [Native function]
If you have to change digits and grouping from English to another language
If you are not sure about your client language
If you don't need to have exact expected result
If you don't care about older version of Safari
// 1000000.2301
parseFloat(num) // (Pre-fix) If the input is string
.toLocaleString('en-US', {
useGrouping: true // (Default is true, here is just for show)
});
// 1,000,000.23
Read more: https://www.w3schools.com/jsref/jsref_tolocalestring_number.asp
Intl.NumberFormat() (Capability - Universality - Compatibility) [Native function]
Almost same as toLocaleString() +
Great capability of supporting currency, units, etc... any language (Modern browsers)
// 1000000.2301
new Intl.NumberFormat('en-US', { // It can be 'fa-IR' : Farsi - Iran
numberingSystem: 'arab'
}).format(num)
// ١٬٠٠٠٬٠٠٠٫٢٣
Read more: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat
With these much options of the native functions, we still can not expect:
Exact result (+ Not parsing the input / Not rounding / Not converting big numbers)
Accepting other languages digits as input
Customizing separators
Trusting browsers support
Performance
So you maybe need a function like any of these:
formatNums() (Compatibility - Ease of use)
Full version (Capability) (Not faster than toLocaleString) - Explain:
function formatNums(num, sep, dec, u) {
// Setting defaults
sep = sep || ','; // Seperator
u = u || '\\d'; // Universal character set \d: 0-9 (English)
// Mixing of Handeling numbers when the decimal character should be changed + Being sure the input is string
if (typeof num != 'string') {
num = String(num);
if (dec && dec != '.') num = num.replace('.', dec); // Replacing sure decimal character with the custom
}
//
return num.replace(RegExp('\\' + (dec || '.') + u + '+|' + u + '(?=(?:' + u + '{3})+(?!' + u + '))', 'g'),
// The RegEx will be like /\.\d+|\d(?=(?:\d{3})+(?!\d))/g if not be customized
// RegEx explain:
// 1) \.\d+ : First try to get any part that started with a dot and followed by any much of English digits, one or more (For ignoring it later)
// 2) | : Or
// 3) \d : Get any 1 char digit
// 3.1) (?=...) : That the next of that should be
// 3.2) (?:\d{3}) : 3 length digits
// 3.2.1) + : One or more of the group
// 3.3) (?!\d) : ...till any place that there is no digits
function(a) { // Any match can be the decimal part or the integer part so lets check it
return a.length == 1 ? a + sep : a // If the match is one character, it is from the grouping part as item (3) in Regex explain so add the seperator next of it, if not, ignore it and return it back.
})
}
function formatNums(num,sep,dec,u) {
sep=sep||',';
u=u||'\\d';
if(typeof num!='string') {
num=String(num);
if( dec && dec!='.') num=num.replace('.',dec);
}
return num.replace(RegExp('\\'+(dec||'.')+u+'+|'+u+'(?=(?:'+u+'{3})+(?!'+u+'))','g'),function(a) {return a.length==1 ? a+sep : a})
}
console.log(formatNums(1000000.2301));
console.log(formatNums(100.2301));
console.log(formatNums(-2000.2301));
console.log(formatNums(123123123,' , '));
console.log(formatNums('0000.0000'));
console.log(formatNums('5000000.00'));
console.log(formatNums('5000000,00',' ',','));
console.log(formatNums(5000000.1234,' ',','));
console.log(formatNums('۱۲۳۴۵۶۷۸۹/۹۰۰۰',',','/','[\\d\\u0660-\\u0669\\u06f0-\\u06f9]'));
Play with the examples here:
https://jsfiddle.net/PAPIONbit/198xL3te/
Light version (Performance) (~30% faster than toLocaleString)
function formatNums(num,sep) {
sep=sep||',';
return String(num).replace(/\.\d+|\d(?=(?:\d{3})+(?!\d))/g,
function(a) {
return a.length==1?a+sep:a
}
);
}
console.log(formatNums(1000000.2301));
console.log(formatNums(100.2301));
console.log(formatNums(-2000.2301));
console.log(formatNums(123123123,' '));
Check the RegEx (Without the necessary function) : https://regexr.com/66ott
(num+'').replace(/\B(?=(?:\d{3})+\b)/g,','); (Performance - Compatibility)
Best choose if The input is Specified / Predefined. (Like usual prices that sure will not have more than 3 decimals)
(~65% faster than toLocaleString)
num=1000000;
str='123123.100';
console.log((num+'').replace(/\B(?=(?:\d{3})+\b)/g,','));
console.log(str.replace(/\B(?=(?:\d{3})+\b)/g,','));
+
For Persian/Arabic local clients:
If your client going to use Persian/Arabic numbers for input as what is usual in Iran, I think the best way is instead of keeping the original characters, convert them to English before you deal with, to you can calculate it.
// ۱۲۳۴۵۶۷۸۹۰
function toEnNum(n) { // Replacing Persian/Arabic numbers character with English
n.replace(/[\u0660-\u0669\u06f0-\u06f9]/g, // RegEx unicode range Persian/Arabic numbers char
function(c) {
return c.charCodeAt(0) & 0xf; // Replace the char with real number by getting the binary index and breaking to lowest using 15
}
);
}
// 1234567890
And for still showing them as original looking there is 2 ways:
CSS Using Persian/Arabic fonts with local digits (My choose)
Convert the result back with Intl.NumberFormat or a function like: https://stackoverflow.com/a/13787021/7514010
My Old-school function on this post: (~15% Faster than toLocalString)
// 10000000.0012
function formatNums(n, s) {
return s = s || ",", String(n).
replace(/(?:^|[^.\d])\d+/g, // First this RegEx take just integer parts
function(n) {
return n.replace(/\B(?=(?:\d{3})+\b)/g, s);
})
}
// 10,000,000.0012
var formatNumber = function (number) {
var splitNum;
number = Math.abs(number);
number = number.toFixed(2);
splitNum = number.split('.');
splitNum[0] = splitNum[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
return splitNum.join(".");
}
EDIT:
The function only work with positive number. for exmaple:
var number = -123123231232;
formatNumber(number)
Output: "123,123,231,232"
But to answer the question above toLocaleString() method just solves the problem.
var number = 123123231232;
number.toLocaleString()
Output: "123,123,231,232"
Cheer!
My answer is the only answer that completely replaces jQuery with a much more sensible alternative:
function $(dollarAmount)
{
const locale = 'en-US';
const options = { style: 'currency', currency: 'USD' };
return Intl.NumberFormat(locale, options).format(dollarAmount);
}
This solution not only adds commas, but it also rounds to the nearest penny in the event that you input an amount like $(1000.9999) you'll get $1,001.00. Additionally, the value you input can safely be a number or a string; it doesn't matter.
If you're dealing with money, but don't want a leading dollar sign shown on the amount, you can also add this function, which uses the previous function but removes the $:
function no$(dollarAmount)
{
return $(dollarAmount).replace('$','');
}
If you're not dealing with money, and have varying decimal formatting requirements, here's a more versatile function:
function addCommas(number, minDecimalPlaces = 0, maxDecimalPlaces = Math.max(3,minDecimalPlaces))
{
const options = {};
options.maximumFractionDigits = maxDecimalPlaces;
options.minimumFractionDigits = minDecimalPlaces;
return Intl.NumberFormat('en-US',options).format(number);
}
Oh, and by the way, the fact that this code does not work in some old version of Internet Explorer is completely intentional. I try to break IE anytime that I can catch it not supporting modern standards.
Please remember that excessive praise, in the comment section, is considered off-topic. Instead, just shower me with up-votes.
I Wrote this one before stumbling on this post. No regex and you can actually understand the code.
$(function(){
function insertCommas(s) {
// get stuff before the dot
var d = s.indexOf('.');
var s2 = d === -1 ? s : s.slice(0, d);
// insert commas every 3 digits from the right
for (var i = s2.length - 3; i > 0; i -= 3)
s2 = s2.slice(0, i) + ',' + s2.slice(i);
// append fractional part
if (d !== -1)
s2 += s.slice(d);
return s2;
}
$('#theDudeAbides').text( insertCommas('1234567.89012' ) );
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="theDudeAbides"></div>
For anyone who likes 1-liners and a single regex, but doesn't want to use split(), here is an enhanced version of the regex from other answers that handles (ignores) decimal places:
var formatted = (x+'').replace(/(\..*)$|(\d)(?=(\d{3})+(?!\d))/g, (digit, fract) => fract || digit + ',');
The regex first matches a substring starting with a literal "." and replaces it with itself ("fract"), and then matches any digit followed by multiples of 3 digits and puts "," after it.
For example, x = 12345678.12345678 will give formatted = '12,345,678.12345678'.
Let me try to improve uKolka's answer and maybe help others save some time.
Use Numeral.js.
document.body.textContent = numeral(1234567).format('0,0');
<script src="//cdnjs.cloudflare.com/ajax/libs/numeral.js/1.4.5/numeral.min.js"></script>
You should go with Number.prototype.toLocaleString() only if its browser compatibilty is not an issue.
Just for future Googlers (or not necessarily 'Googlers'):
All of solutions mentioned above are wonderful, however, RegExp might be awfully bad thing to use in a situation like that.
So, yes, you might use some of the options proposed or even write something primitive yet useful like:
const strToNum = str => {
//Find 1-3 digits followed by exactly 3 digits & a comma or end of string
let regx = /(\d{1,3})(\d{3}(?:,|$))/;
let currStr;
do {
currStr = (currStr || str.split(`.`)[0])
.replace( regx, `$1,$2`)
} while (currStr.match(regx)) //Stop when there's no match & null's returned
return ( str.split(`.`)[1] ) ?
currStr.concat(`.`, str.split(`.`)[1]) :
currStr;
};
strToNum(`123`) // => 123
strToNum(`123456`) // => 123,456
strToNum(`-1234567.0987`) // => -1,234,567.0987
The regexp that's used here is fairly simple and the loop will go precisely the number of times it takes to get the job done.
And you might optimize it far better, "DRYify" code & so on.
Yet,
(-1234567.0987).toLocaleString();
(in most situations) would be a far better choice.
The point is not in the speed of execution or in cross-browser compatibility.
In situations when you'd like to show the resulting number to user, .toLocaleString() method gives you superpower to speak the same language with the user of your website or app (whatever her/his language is).
This method according to ECMAScript documentation was introduced in 1999, and I believe that the reason for that was the hope that the Internet at some point will connect people all around the world, so, some "internalization" tools were needed.
Today the Internet does connect all of us, so, it is important to remember that the world is a way more complex that we might imagine & that (/almost) all of us are here, in the Internet.
Obviously, considering the diversity of people, it is impossible to guarantee perfect UX for everybody because we speak different languages, value different things, etc. And exactly because of this, it is even more important to try to localize things as much as it's possible.
So, considering that there're some particular standards for representation of date, time, numbers, etc. & that we have a tool to display those things in the format preferred by the final user, isn't that rare and almost irresponsible not to use that tool (especially in situations when we want to display this data to the user)?
For me, using RegExp instead of .toLocaleString() in situation like that sounds a little bit like creating a clock app with JavaScript & hard-coding it in such a way so it'll display Prague time only (which would be quite useless for people who don't live in Prague) even though the default behaviour of
new Date();
is to return the data according to final user's clock.
An alternative way, supporting decimals, different separators and negatives.
var number_format = function(number, decimal_pos, decimal_sep, thousand_sep) {
var ts = ( thousand_sep == null ? ',' : thousand_sep )
, ds = ( decimal_sep == null ? '.' : decimal_sep )
, dp = ( decimal_pos == null ? 2 : decimal_pos )
, n = Math.floor(Math.abs(number)).toString()
, i = n.length % 3
, f = ((number < 0) ? '-' : '') + n.substr(0, i)
;
for(;i<n.length;i+=3) {
if(i!=0) f+=ts;
f+=n.substr(i,3);
}
if(dp > 0)
f += ds + parseFloat(number).toFixed(dp).split('.')[1]
return f;
}
Some corrections by #Jignesh Sanghani, don't forget to upvote his comment.
I think this function will take care of all the issues related to this problem.
function commaFormat(inputString) {
inputString = inputString.toString();
var decimalPart = "";
if (inputString.indexOf('.') != -1) {
//alert("decimal number");
inputString = inputString.split(".");
decimalPart = "." + inputString[1];
inputString = inputString[0];
//alert(inputString);
//alert(decimalPart);
}
var outputString = "";
var count = 0;
for (var i = inputString.length - 1; i >= 0 && inputString.charAt(i) != '-'; i--) {
//alert("inside for" + inputString.charAt(i) + "and count=" + count + " and outputString=" + outputString);
if (count == 3) {
outputString += ",";
count = 0;
}
outputString += inputString.charAt(i);
count++;
}
if (inputString.charAt(0) == '-') {
outputString += "-";
}
//alert(outputString);
//alert(outputString.split("").reverse().join(""));
return outputString.split("").reverse().join("") + decimalPart;
}
If you're looking for a short and sweet solution:
const number = 12345678.99;
const numberString = String(number).replace(
/^\d+/,
number => [...number].map(
(digit, index, digits) => (
!index || (digits.length - index) % 3 ? '' : ','
) + digit
).join('')
);
// numberString: 12,345,678.99
I think your solution is one of the shorter ones I've seen for this. I don't think there are any standard JavaScript functions to do this sort of thing, so you're probably on your own.
I checked the CSS 3 specifications to see whether it's possible to do this in CSS, but unless you want every digit in its own <span>, I don't think that's possible.
I did find one project on Google Code that looked promising: flexible-js-formatting. I haven't used it, but it looks pretty flexible and has unit tests using JsUnit. The developer also has a lot of posts (though old) about this topic.
Be sure to consider international users: lots of nations use a space as the separator and use the comma for separating the decimal from the integral part of the number.

Why does C print different values than what PHP prints?

This is a complete noob question.
So here is my code in C,
#include<stdio.h>
int main()
{
int I, X=4;
double I0;
double COEFF1[7];
double COEFF2[9];
/*Coefficient 1 I0*/
COEFF1[0]=0.0045813;
COEFF1[1]=0.0360768;
COEFF1[2]=0.2659732;
COEFF1[3]=1.2067492;
COEFF1[4]=3.0899424;
COEFF1[5]=3.5156229;
COEFF1[6]=1.0000000;
/*Coefficient 2 I0*/
COEFF2[0]=0.00392377;
COEFF2[1]=-0.01647633;
COEFF2[2]=0.02635537;
COEFF2[3]=-0.02057706;
COEFF2[4]=0.00916281;
COEFF2[5]=-0.00157565;
COEFF2[6]=0.00225319;
COEFF2[7]=0.01328592;
COEFF2[8]=0.39894228;
if(X>=3.75)
{
I0=COEFF2[0];
for(I=1;I<9;I++)
{
I0=(3.75/X)*I0+COEFF2[I];
printf("%i\n", I0);
}
//return I0/(sqrt(X)*exp(-X));
}
else
{
I0=COEFF1[0];
for(I=1;I<7;I++)
{
I0=I0*(X/3.75)*(X/3.75)+COEFF1[I];
}
//return I0;
}
return 0;
}
And with little housekeeping, this is my translated code in PHP,
<?php
$coeff1 =array();
$coeff2 =array();
/*Coefficient 1 $i0*/
$coeff1[0]=0.0045813;
$coeff1[1]=0.0360768;
$coeff1[2]=0.2659732;
$coeff1[3]=1.2067492;
$coeff1[4]=3.0899424;
$coeff1[5]=3.5156229;
$coeff1[6]=1.0000000;
/*Coefficient 2 $i0*/
$coeff2[0]=0.00392377;
$coeff2[1]=-0.01647633;
$coeff2[2]=0.02635537;
$coeff2[3]=-0.02057706;
$coeff2[4]=0.00916281;
$coeff2[5]=-0.00157565;
$coeff2[6]=0.00225319;
$coeff2[7]=0.01328592;
$coeff2[8]=0.39894228;
$x = 4;
if($x>=3.75)
{
$i0=$coeff2[0];
for($i=1;$i<9;$i++)
{
$i0=(3.75/$x)*$i0+$coeff2[$i];
printf($i0."<br />");
}
//return $i0/(sqrt($x)*exp(-$x));
}
else
{
$i0=$coeff1[0];
for($i=1;$i<7;$i++)
{
$i0=$i0*($x/3.75)*($x/3.75)+$coeff1[$i];
}
//return $i0;
}
?>
But why won't they generate the same result?
http://imageshack.com/a/img59/3402/98ak.jpg
Please help. I'm stuck.
%i is the format specifier for int; I0 has type double but printf is being told to interpret it as int. You should use %f for doubles instead:
printf("%f\n", I0);
Maybe this bit might be useful too.
The difference in the output of the two programs can be attributed indeed to the line
printf("%i\n", I0);
in your C program where I0 is interpreted as an integer but its bit pattern was stored as a double type which uses different logic for organizing the bits (and in the standard variation also uses a different number of bits). What the printf function does is that it just takes whatever that bit pattern was (in the length of an integer) and prints it out like it was an integer - because you told it so (%i), hence the output of the program.
PHP uses dynamic type definition so your variables are interpreted in the context in which they are used (unless sometimes forced to be a certain type by casting or using settype()).
I.e.: $a = 1; will be an integer but if you do another assignment like $a += 0.5; it will be casted into a float automatically.

a = (a + b) - (b = a); C++ vs php

I've been looking around and found formula: a = (a + b) - (b = a) it is supposed to swap two variables (or objects in some cases). However I tested it with C++ and php, these gave me different result.
php:
$a = 10;
$b = 20;
$a = ($a + $b) - ($b = $a);
echo $a, " ", $b;
This prints 20 10
C++
int a = 10;
int b = 20;
a = (a + b) - (b = a);
std::cout << a << " " << b;
This prints 10 10
Code looks the same but outputs are different, I've been thinking about two reasons:
C++ code is compiling and php is interpreting.
This formula is useless because it leads to undefined behavior.
Can somebody explains, why C++ and php output differs in this situation?
I'm not sure what the rules are in PHP, but in C++, the order of individual sub-expressions isn't strictly defined, or as the technical term is, it is "unspecified" - in other words, the compiler is allowed to calculate b = a before or after it does a + b. As long as it does a + b and b = a before the subtraction. The use of "unspecified" behaviour allows the compiler to produce more efficient code in some cases, or simply that it's possible to build a compiler for some architectures.
It also means that if you have an expression that "recalculates" a value within the expression itself, and also using it elsewhere in the expression, you get unedefined behaviour (UB for short). UB means just that, the behaviour is not defined - almost anything could happen, including what you are seeing and many other alternatives (e.g. the compiler is allowed to produce 42 as a result as well, even if logic says the answer wouldn't be 42 in this case [it's the wrong question for that!]).
I would also suggest that if you want to swap two values, in PHP:
$t = $a;
$a = $b;
$b = $t;
and in C++:
#include <algorithm>
std::swap(a, b);
or if you insist on writing your own:
int t = a;
a = b;
b = t;
Trying to be clever and perform it "without temporary variable" is almost certainly going to make it slower than the use of a temporary - certainly in a compile language like C++ - in a interpreted language like PHP, creating a new variable may add a bit of extra overhead, but it's unlikely to be that big, compared to the extra effort in the logic required.
C++ code is completely broken because of undefined behavior. (read and write b in one sequence point).
For PHP:
$a = 10;
$b = 20;
$a = ($a + $b) - ($b = $a);
//executes like thus
$a = (30) - ($b = $a);
$a = (30) - ($b = $a = 10); //new $a still not computed, using older $a
$a = (30) - (10);
$a = 20;
//then, $a=20 and $b = 10
This is totally related to Operator Precedence, this might be same in C or might not, it depends on precedence if unexpected behavior not occur.

Calculating Colour Contrast for ASP

I found this code snippet for PHP and Javascript, but I was wondering if it could be made work in classic asp? Here's a whole article on the topic for reference.
http://24ways.org/2010/calculating-color-contrast/
PHP code
function getContrast50($hexcolor){
return (hexdec($hexcolor) > 0xffffff/2) ? 'black':'white';
}
Well, nothing built into the language. Converting hex to decimal is as easy as CLng("&H" & hexValue) but from quick look in the PHP manual I saw that hexdec() method ignores any invalid characters, while the VBScript CLng() will just crash.
So here is a working function that as far as I can tell doing the same thing:
Function GetContrast50(hexColor)
Const strValidChars = "1234567890abcdef"
Dim maxValue, decValue, sanitizedColor
Dim x, curChar
sanitizedColor = ""
For x=1 To Len(hexColor)
curChar = LCase(Mid(hexColor, x, 1))
If InStr(strValidChars, curChar)>0 Then
sanitizedColor = sanitizedColor & curChar
End If
Next
If Len(sanitizedColor)=0 Then
GetContrast50 = "invalid color string"
Exit Function
End If
maxValue = CLng("&H" & "ffffff")
decValue = CLng("&H" & sanitizedColor)
If decValue > (maxValue / 2) Then
GetContrast50 = "black"
Else
GetContrast50 = "white"
End If
End Function
It's pretty easy to extend the validation to check the given string is in valid range.

Algorithm for difference of products of large integers

I'm searching for an algorithm to solve differences of the type ab-cd, where a, b, c, and d are integers at the edge of the type capacity, i.e. ab overflows or loses digits depending on the actual representation on the machine. I cannot use arbitrary precision math; one of the platforms will be a SQL database.
I consider something like decomposing the product into (a'+a'')b-(c'+c'')d and then somehow iterate the way down. But probably there is a much more efficient method or at least a clever idea how to do the decomposition. Unfortunately in most cases a,b; c,d; a,c; b,d are coprime, so reduction at least is not simple.
Any ideas?
WARNING
This method is only partially functional. There are cases that it can't solve.
Taken from your text:
I'm searching for an algorithm to solve differences of the type ab-cd,
where a, b, c, and d are integers at the edge of the type capacity,
As I understand you want to calculate (a * b) - (c * d) avoiding a numeric overflow. And you want to solve this with an algorithm.
The first thing we need to recognize is that the result of (a * b) - (c * d) may not fit in the data type. I'll not try to solve those cases.
So, I'll search for different ways to calculate "ab-cd". What I've found is this:
(a * b) - (c * d) = ((a - c) * b) - (c * (d - b))
You can re-order the variables to get different products and therfore increasing the chance of finding a case that will allow you to calculate the operation without the dreaded numeric overflow:
((a - d) * b) - (d * (c - b))
((b - c) * a) - (c * (d - a))
((a - c) * b) - (c * (d - b))
((b - d) * c) - (b * (c - a))
((a - d) * c) - (a * (c - b))
((b - c) * d) - (b * (d - a))
((a - c) * d) - (a * (d - b))
Also notice that this are still differences of products, meaning that you can apply them recursively until you find one that works. For example:
Starting with:
(a * b) - (c * d)
=>
Using the transformation:
((a - d) * b) - (d * (c - b))
=>
By substitution:
(e * b) - (d * f)
=>
Rinse an repeat:
((e - f) * b) - (f * (d - b))
Of course we need to make sure we aren't going to run into a numeric overflow by doing this. Thankfully it is also possible to test if a particular product will cause a numeric overflow (without actually doing the product) with the following approach:
var max = MaxValue;
var min = MinValue;
if (a == 0 || b == 0)
{
return false;
}
else
{
var lim = a < 0 != b < 0 ? min : max;
if ((a < 0 == b < 0) == a < 0)
{
return lim / a > b;
}
else
{
return lim / a < b;
}
}
Also, it is also possible to test if a particular difference will cause a numeric overflow (without actually doing the difference) with the following approach:
var max = MaxValue;
var min = MinValue;
if (a < 0 == b < 0)
{
return true;
}
else
{
if (a < 0)
{
if (b > 0)
{
return min + b < a;
}
else
{
return min - b < a;
}
}
else
{
if (b > 0)
{
return max - b > a;
}
else
{
return max + b > a;
}
}
}
With that it is possible to pick an expression from the eight above that will allow you to calculate without the numeric overflow.
But... Sometimes none of those works. And it seems to be that there are cases where not even their combinations works (ie. rinse and repeat dosn't work)*. Maybe there are other identities that can complete the picture.
*: I did try using some heuristic to explore the combinations and also did try random exploration, there is the risk that I didn't pick good heuristics and I didn't have "luck" with the random. That's why I can't tell for sure.
I want to think that I've done some progress... But with respect to the original problem I've ultimately failed. May be I'll get back to this problem when I have more time... or may be I'll just play video games.
The standard way I know of to address this type of issues is to do what humans do with numbers beyond one digit, which is the limit of our natural counting with fingers. We carry numbers forward.
For example, let's say the limit of numbers in your numeric calculator is 256 (2^8). To get the difference of (243*244)-(242*245), we would need to decompose the numbers into
Label | Part 1 (shifted 2 right) | Part 2 (remainder)
a 2 43
b 2 44
c 2 42
d 2 45
You'd need an array to store the individual digits of the result, or a string. I think an array is faster, but a string more convenient and visible (for debugging).
(a*b)-(c*d)
=> a1*b1 shift4 + a1*b2 shift2 + a2*b1 shift2 + a2*b2
- c1*d1 shift4 + c1*d2 shift2 + c2*d1 shift2 + c2*d2
=> 987654321 (right-aligned string positioning)
+ 4xxxx
+ 88xx
+ 86xx
+ 1892
- 4xxxx
- 90xx
- 84xx
- 1890
==========
2
A naive implementation would work through each step independently, pushing each digit into place and carrying it forward where necessary. There are probably tomes of literature about optimizing these algorithms, such as breaking this into array slots of 2 digits each (since your register of number-limit 256 can handle the addition of 2 2-digit numbers easily).
If your products are near the limits of Int32 you can use Int64.
You can use BC Math Functions to work with large number which on both 32 bit & 64 bit systems
Example Of Large Numbers
$a = "4543534543543534543543543543545";
$b = "9354354546546756765756765767676";
$c = "5654656565656556565654656565656";
$d = "4556565656546546546546546356435" ;
var_dump(calculate($a, $b, $c, $d));
Output
string '257010385579862137851193415136408786476450997824338960635377204776397393100227657735978132009487561885957134796870587800' (length=120)
Function Used
function calculate($a, $b, $c, $d)
{
return bcmul(bcmul(bcmul(bcsub($a, $c),bcsub($a, $d)),bcsub($b, $c)),bcsub($b, $d));
}
After playing a little bit more I found a simpler algorithm following my original idea. It may be somewhat slower than the combined multiplication because it requires real multiplication and division instead of only shifts and addition, but I didn't benchmark it so far concerning the performance in an abstract language.
The idea is the following rewrite ab-cd = (a'+q*d)b-cd = a'b-(c-qb)d = a'b-c'd
The algorithm seems to convert the fastest if you order ab-cd as a>b and c>d, i.e. reduce the biggest numbers and maximize q.
q=(int)floor((a>c)? a/d : c/b);
a -= q*d;
c -= q*b;
Now reorder and start again. You can finish as soon as all numbers are small enough for safe multiplication, any number becomes smaller than 2 or even negative, or you find the same value for any of the numbers on both sides.

Categories