g | x | w | all
Bytes Lang Time Link
010AWK250915T171843Zxrs
210JavaScript230207T110405ZEzioMerc
069Charcoal230206T130619ZNeil
162bc230209T143249Zroblogic
030bash230208T094628ZSamR
007Dyalog APL230208T002217Zvcoutass
015Raku230206T123316ZJo King
046PHP 8.x + BC Math230208T002412ZIsmael M
nan230207T212602Zuser1167
009Excel230206T093030ZJos Wool
084Python230206T175710ZThe Thon
319Japt230206T093958ZShaggy
163PARI/GP230207T082741Zalephalp
048Factor + decimals230206T200750Zchunes
102Java 8230206T101754ZKevin Cr
nanFig230206T164202ZSeggan

AWK, 10 bytes

1,$0=$1+$2

Attempt This Online!

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+$//"

Try it online!

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.

Try it online!

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$]/}

Try it online!

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

+/⍎¨

Try it online!

Explanation:

+/⍎¨
   ¨  ⍝ Map each element in the array
  ⍎   ⍝ Execute expression, which converts from string to integer
 /    ⍝ Reduce 
+     ⍝ Sum

Raku, 17 15 bytes

$~*+*o**.FatRat

Try it online!

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.


You can try it on here - with testcases:
https://onlinephp.io?s=VVHNSsNAED4byDvMIbAJbLabpH9RY_EgeBDswVsIkiYbItSmJNsiiG8gePGo7-Hz-AK-gpPduK17mJn9vvnmhzlfbOutbdnWaASX6zVI0Uko8k50tuU8QQKpbZ2kJCAUtAlJRhXE-99gBig2WYHBOA8Y52EPRmzMlWCMgakz6RF_wv6XUgI_ZJrl6AciCKOxAqezeaw0cx5GhvYnnE3VnKiJlDjijM8Mr-dRvXiggzg-YtkAYs_wL4jMMkxth5R2hkDR4Q2qIyTQbQ6PHX9IZlvZ2XCEu1pA0ZQCZJ1LKBvRQSd3VYXnqDZ4j2rjOjl1Vl5y0cr24dHVdlXkZek6K4pkHHuUe5Qw4qmqVdOKvKhdvGfegbP3nnFmpxXdbi2xotOX3Kc8o8ilQdaLTkRRN2BykqSnwgwWQL4_3n--3gicYvj52i8GPqAbkiksr5f3V7c3WOXlFw%2C%2C&v=8.2.1

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*

Attempt This Online!

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

Try it

Outputs an string, subject to floating point inaccuracies.

x s

Try it

Outputs a string, with no floating point inaccuracies.

x x¡X°s q. hP ÌÊÃrÔ

Try it

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)),""))

Attempt This Online!

Factor + decimals, 48 bytes

[ [ string>decimal ] bi@ D+ unparse " " split1 ]

enter image description here

[ 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()

Try it online.

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)

Fig, \$5\log_{256}(96)\approx\$ 4.116 bytes

B+_x_

Try it online!

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