| Bytes | Lang | Time | Link |
|---|---|---|---|
| 010 | AWK | 250915T171843Z | xrs |
| 210 | JavaScript | 230207T110405Z | EzioMerc |
| 069 | Charcoal | 230206T130619Z | Neil |
| 162 | bc | 230209T143249Z | roblogic |
| 030 | bash | 230208T094628Z | SamR |
| 007 | Dyalog APL | 230208T002217Z | vcoutass |
| 015 | Raku | 230206T123316Z | Jo King |
| 046 | PHP 8.x + BC Math | 230208T002412Z | Ismael M |
| nan | 230207T212602Z | user1167 | |
| 009 | Excel | 230206T093030Z | Jos Wool |
| 084 | Python | 230206T175710Z | The Thon |
| 319 | Japt | 230206T093958Z | Shaggy |
| 163 | PARI/GP | 230207T082741Z | alephalp |
| 048 | Factor + decimals | 230206T200750Z | chunes |
| 102 | Java 8 | 230206T101754Z | Kevin Cr |
| nan | Fig | 230206T164202Z | Seggan |
AWK, 10 bytes
1,$0=$1+$2
This generally works, but output isn't perfect for some numbers.... But, AWK treats input as a string and/or number, so e.g. you can edit numbers with string functions.
JavaScript, 210 bytes
(a,b)=>([a,c='']=a.split`.`,[b,d='']=b.split`.`,m=c[k='length'],e=(o=(g=i=>BigInt(i+c.padEnd(l=m>d[k]?m:d[k],0)))(a)+g(b,c=d)+'')[k]-l,h=o.slice(0,e),i=o.slice(e).replace(/0+$/,''),(!h|h=='-'?h+0:h)+(i&&'.'+i))
(a,b)=>( // Define function
[a,c='']=a.split`.`, // a - integer part of number a
// c - decimal part of number a (default value is '')
[b,d='']=b.split`.`, // b - integer part of number b
// d - decimal part of number b (default value is '')
m=c[k='length'], // m - length of c
// k - 'length' key
e=( // e - decimal point position
o= // o - sum of BigInts as string
(g=i=>BigInt( // g - function which convert string to BigInt
i+
c.padEnd(
l=m>d[k]?m:d[k], // l - the length of longest decimal part
0
)
))(a)+
// c.padEnd(l, '0') - adding to the end of decimal
// part as many zeros as it need to
// be the length of 'l'`
// i + c.padEnd(l, '0') - same number as in input
// without decimal point and possibly
// with trailing zeros
g(b,c=d)+ // now c is decimal part of number b
'' // added to convert BigInt to string
)[k]-l,
h=o.slice(0,e), // h - integer part of result
i=o.slice(e).replace(/0+$/,''), // i - decimal part of result
(!h|h=='-'?h+0:h) // if h is empty string or minus
// then add zero else do nothing
+ // concatenate of integer part of result
// and decimal part of result
(i&&'.'+i) // if i is empty string then
// return empty string else
) // add leading dot
Try it:
f=(a,b)=>([a,c='']=a.split`.`,[b,d='']=b.split`.`,m=c[k='length'],e=(o=(g=i=>BigInt(i+c.padEnd(l=m>d[k]?m:d[k],0)))(a)+g(b,c=d)+'')[k]-l,h=o.slice(0,e),i=o.slice(e).replace(/0+$/,''),(!h|h=='-'?h+0:h)+(i&&'.'+i))
;[
['1', '1'], // '2'
['0', '0'], // '0'
['9', '1'], // '10'
['001.002', '3.400'], // '4.402'
['5', '-5.0'], // '0'
['2', '-2.5'], // '-0.5'
['12345', '67890'], // '80235'
['-50.6', '20.53'], // '-30.07'
['-001.00', '00100'], // '99'
['-00.100', '-0.20'], // '-0.3'
['0.1', '0.2'], // '0.3'
['1000000000000', '-0.000000000001'], // '999999999999.999999999999'
].map(x => {
console.log(f(x[0], x[1]));
console.log(f(x[1], x[0]));
})
Charcoal, 72 69 bytes
≔E²Sθ≔Eθ∧№ι.⌕⮌ι.η≔ΣIEθ⁺⁻ι.×0⁻⌈η§ηκθ≔Xχ⌈ηη‹θ⁰I÷↔θη¿﹪θη«.W﹪↔θη«≧÷χηI÷ιη
Try it online! Link is to verbose version of code. Feels very long somehow. Explanation:
≔E²Sθ
Input the two strings.
≔Eθ∧№ι.⌕⮌ι.η
See how many digits each has after the decimal (if any).
≔ΣIEθ⁺⁻ι.×0⁻⌈η§ηκθ
Scale them both to be integers and take the sum.
≔Xχ⌈ηη‹θ⁰I÷↔θη
Calculate the effect of the scaling and output the integer part of the result.
¿﹪θη«.
If the result is not an integer then output a ..
W﹪↔θη«≧÷χηI÷ιη
Output successive digits until the remainder is zero.
40 bytes by importing Python's decimal.Decimal:
≔IΣE²▷⪫⟦d¦.Dω⟧ecimalSθW›№θ.Σ§θ±¹≔…θ⊖Lθθθ
Attempt This Online! Link is to verbose version of code. Explanation:
≔IΣE²▷⪫⟦d¦.Dω⟧ecimalSθ
Input the two strings, convert them to decimal.Decimal, take the sum, then cast back to string again.
W›№θ.Σ§θ±¹
Repeat while the string contains a . and does not end in a digit 1-9...
≔…θ⊖Lθθ
... remove the last character.
θ
Output the final string.
bc, 162 bytes
x=a+b;y=x/1;if(y==x)x=y;if(x==0||x<=-1||x>=1){print x,"\n";return}
if(scale(x)>1&&x*10^length(x)%10==0){scale=1;y=x/1.0;x=y};if(x<0)print "-0",-x else print "0",x
Try it online!. Adapted from a great s.o answer.
Explanation
x=a+b starting out simple
y=x/1;if(y==x)x=y drop trailing 0's after the decimal
(99.00 --> 99 )
if(x==0||x<=-1||x>=1) if x==0 or abs(x)>=1 then just print it
return preferable to `else{...}`, IMO.
From now on x is between -1 and 1.
if(scale(x)>1 if x has an gnarly decimal
&&x*10^length(x)%10==0) and the last digit is 0
{scale=1;y=x/1.0;x=y} drop trailing 0's & keep significant digits
(-.300 --> -.3)
if(x<0)print "-0",-x (-.3 --> -0.3)
else print "0",x ( .5 --> 0.5)
bash, + bc, 30 bytes
bc<<<$1+$2|sed -r "s/\.*0+$//"
How?
This takes advantage of bc being an arbitrary precision calculator language. It pipes the input (expected to be two arguments) to bc which adds them.
10 bytes to do the calculation, bc<<<$1+$2. 20 bytes to pipe to sed and remove trailing zeroes.
The golf-y bit is replacing echo with the bash here string (<<<), as in this tip. The code is the equivalent of echo $1+$2 | bc. This is my first attempt at a challenge in a language other than R. I would be interested in tips to golf further.
Example output
I am not exactly sure how to provide a list of string test cases on TIO. In the absence of that, here is the example output for the final test case on my machine (script is called calc.sh):
$ ./calc.sh '1000000000000' '-0.000000000001'
999999999999.999999999999
$ ./calc.sh '-00.100' '-0.20'
-.3
bash + bc, 31 bytes
This did not strip all trailing zeroes, as pointed out in the comments by @roblogic.
m=`bc<<<$1+$2`
echo ${m//[0$]/}
Answer which did not meet spec, 10 bytes
bc<<<$1+$2
Unfortunately, as pointed out by
Ismael Miguel
in the comments, the question says to
return the result (which is also a correct number) without any leading zeros in the integer part, trailing zeros in the decimal part and without minus if the answer is 0
This did not remove all trailing zeroes.
Dyalog APL, 7 bytes
+/⍎¨
Explanation:
+/⍎¨
¨ ⍝ Map each element in the array
⍎ ⍝ Execute expression, which converts from string to integer
/ ⍝ Reduce
+ ⍝ Sum
Raku, 17 15 bytes
$~*+*o**.FatRat
This converts both arguments to FatRats (arbitrary sized bignums), before adding them together and stringifying the result. You could remove the o**.FatRat part, but this would use Rats, which decay to floating point numbers once the precision needed is too high.
PHP 8.x + BC Math, 46 bytes
It's a bit longer than expected, but does the job.
fn($a,$b)=>rtrim(rtrim(bcadd($b,$a,99),0),'.')
This creates an anonymous function that returns the expected result.
How does it work?
It uses the bcadd function to do all the math, using an obnoxiously high scale, just to be safe.
That function accepts 2 strings and returns a string with the calculations made.
After that, removes all 0's from the right, then the period (.).
If none is found, does nothing to the result.
Extremely long URL to avoid saving it on the website
tcl:
expr $A+$B
Tcl has no concept of a "number"; everything is a string. Some strings can be interpreted as numbers, which is what "expr" does above. Literally "take the contents of the variables "A" and "B", put a "+" between the two and treat the result as interpretable as an expression (and return the result of that expression)"
Excel, 7 9 bytes
=A1+B1&""
Python, 84 bytes
lambda*x:(s:=str(sum(map(Decimal,x))))[-2:]=='.0'and s[:-2]or s
from decimal import*
Normal numbers succumb to floating point inaccuracies, so we need to convert to decimal.Decimal.
Japt, 1, 3 or 19 bytes
None of these can handle the last test case as the decimal exceeds JavaScript's native number support. Links include all other test cases, taking input as an array of 2 strings.
Outputs an integer, subject to floating point inaccuracies.
x
Outputs an string, subject to floating point inaccuracies.
x s
Outputs a string, with no floating point inaccuracies.
x x¡X°s q. hP ÌÊÃrÔ
PARI/GP, 163 bytes
g(s)=eval(strjoin(t=strsplit(s,".")))/10^if(#t>1,#t[2])
h(n)=if(n*=10,Str(n\1,h(n-n\1)),"")
f(a,b)=Str(if(0>t=g(a)+g(b),t=-t;"-","")d=t\1,if(t-=d,Str("."h(t)),""))
Factor + decimals, 48 bytes
[ [ string>decimal ] bi@ D+ unparse " " split1 ]
[ string>decimal ] bi@ ! convert both inputs to the decimal data type (arbitrary size decimals)
D+ ! add them together
unparse ! convert prettyprinted format to string
" " split1 ! remove DECIMAL: prefix
Java 8, 103 102 bytes
import java.math.*;a->b->new BigDecimal(a).add(new BigDecimal(b)).stripTrailingZeros().toPlainString()
Explanation:
import java.math.*; // Required import for BigDecimal
a->b-> // Method with String as two parameters & return-type
new BigDecimal(a) // Convert the first input to a BigDecimal
.add( // Plus:
new BigDecimal(b)) // The second input as BigDecimal
.stripTrailingZeros() // Remove any no-op trailing 0s
.toPlainString() // Convert and return it as plain String (so no scientific
// notation)
- Try it online without
.stripTrailingZeros()(fails for test cases"5"+"-5.0" = "0.0";"-001.00"+"00100" = "99.00";"-00.100"+"-0.20" = "-0.300"). - Try it online without
.toPlainString()(fails for test case"9"+"1" = "1E+1").
Fig, \$5\log_{256}(96)\approx\$ 4.116 bytes
B+_x_
Since Fig uses BigDecimals, this doesn't suffer from floating point issues as some other answers do.
B+_x_
_ # Convert first input to number
_x # Convert second input to number
+ # Add
B # Convert to string
