0

I am trying to get the sum my floating point values, I am getting very weird output like 8 decimal places and other undesired results. What I want to do is just add all the objects protein values for example into a sum i.e 200.1

**

DATA

**

**

[{"upload_date":"2019-12-31T21:41:42.943Z","item":"hot_dog","protein_content":"10.00","carb_content":"25.00","fat_content":"15.00","calories":"1170.00"},{"upload_date":"2019-12-31T21:41:56.604Z","item":"fried_rice","protein_content":"3.50","carb_content":"64.30","fat_content":"28.00","calories":"2188.00"},{"upload_date":"2019-12-31T21:43:06.372Z","item":"greek_salad","protein_content":"6.60","carb_content":"10.30","fat_content":"19.40","calories":"1079.00"},{"upload_date":"2019-12-31T21:42:56.577Z","item":"fried_rice","protein_content":"3.50","carb_content":"64.30","fat_content":"28.00","calories":"2188.00"},{"upload_date":"2019-12-31T21:42:45.559Z","item":"steak","protein_content":"25.10","carb_content":"0.00","fat_content":"0.50","calories":"445.00"},{"upload_date":"2019-12-31T21:42:28.609Z","item":"hot_dog","protein_content":"10.00","carb_content":"25.00","fat_content":"15.00","calories":"1170.00"},{"upload_date":"2019-12-31T21:42:15.793Z","item":"steak","protein_content":"25.10","carb_content":"0.00","fat_content":"0.50","calories":"445.00"},{"upload_date":"2019-12-31T21:42:05.049Z","item":"greek_salad","protein_content":"6.60","carb_content":"10.30","fat_content":"19.40","calories":"1079.00"}]

CODE

**

for(let i = 0; i < dietInfo.length; i++) {
     this.protein +=  dietInfo[i].protein_content
     this.calories += parseFloat(dietInfo[i].calories)
     this.carbs += parseFloat(dietInfo[i].carbs_content)
     this.fat += parseFloat(dietInfo[i].fat_content)
    //  this.protein = parseFloat(this.protein).toFixed(1)
}
console.log('before:', this.protein);
// round of inaccuracies, assuming decimals
this.protein = Math.round(this.protein*100000000)/100000000;
console.log('after:', this.protein);
Invic18
  • 137
  • 2
  • 11
  • 4
    Your data should contain *numbers*, not strings with numbers in them, ideally. And what you're seeing is normal computer (not just JavaScript) floating-point math. – Pointy Dec 31 '19 at 23:31
  • Does this answer your question? [Is floating point math broken?](https://stackoverflow.com/questions/588004/is-floating-point-math-broken) – VLAZ Jan 01 '20 at 00:40

2 Answers2

1

You can use your current dataset and run it through an Array.reduce function so add your numbers up. I'm a little unclear on the desired output so the below example spits out an object of protein, carbs, fat and calories.

const data = [{"upload_date":"2019-12-31T21:41:42.943Z","item":"hot_dog","protein_content":"10.00","carb_content":"25.00","fat_content":"15.00","calories":"1170.00"},{"upload_date":"2019-12-31T21:41:56.604Z","item":"fried_rice","protein_content":"3.50","carb_content":"64.30","fat_content":"28.00","calories":"2188.00"},{"upload_date":"2019-12-31T21:43:06.372Z","item":"greek_salad","protein_content":"6.60","carb_content":"10.30","fat_content":"19.40","calories":"1079.00"},{"upload_date":"2019-12-31T21:42:56.577Z","item":"fried_rice","protein_content":"3.50","carb_content":"64.30","fat_content":"28.00","calories":"2188.00"},{"upload_date":"2019-12-31T21:42:45.559Z","item":"steak","protein_content":"25.10","carb_content":"0.00","fat_content":"0.50","calories":"445.00"},{"upload_date":"2019-12-31T21:42:28.609Z","item":"hot_dog","protein_content":"10.00","carb_content":"25.00","fat_content":"15.00","calories":"1170.00"},{"upload_date":"2019-12-31T21:42:15.793Z","item":"steak","protein_content":"25.10","carb_content":"0.00","fat_content":"0.50","calories":"445.00"},{"upload_date":"2019-12-31T21:42:05.049Z","item":"greek_salad","protein_content":"6.60","carb_content":"10.30","fat_content":"19.40","calories":"1079.00"}];

const result = data.reduce( (acc, curr) => {
  acc.protein_content += parseFloat(curr['protein_content']);
  acc.carb_content += parseFloat(curr['carb_content']);
  acc.fat_content += parseFloat(curr['fat_content']);
  acc.calories += parseFloat(curr['calories']);
  return acc;
}, {protein_content: 0, carb_content: 0, fat_content: 0, calories: 0});

console.log(result);
mwilson
  • 12,295
  • 7
  • 55
  • 95
  • this did work for a bit but when I hooked it into my pie chart some of the floating points added excess numbers behind the decimal. I think the roundDigit function that the other guy provided protected against this. Thanks for your submission though! – Invic18 Jan 01 '20 at 18:20
1

JavaScript floating point math is subject to inacuracies, as you can see in this issue.

You can just round to the desired digit by using the following:

const dietInfo =  [{"upload_date":"2019-12-31T21:41:42.943Z","item":"hot_dog","protein_content":"10.00","carb_content":"25.00","fat_content":"15.00","calories":"1170.00"},{"upload_date":"2019-12-31T21:41:56.604Z","item":"fried_rice","protein_content":"3.50","carb_content":"64.30","fat_content":"28.00","calories":"2188.00"},{"upload_date":"2019-12-31T21:43:06.372Z","item":"greek_salad","protein_content":"6.60","carb_content":"10.30","fat_content":"19.40","calories":"1079.00"},{"upload_date":"2019-12-31T21:42:56.577Z","item":"fried_rice","protein_content":"3.50","carb_content":"64.30","fat_content":"28.00","calories":"2188.00"},{"upload_date":"2019-12-31T21:42:45.559Z","item":"steak","protein_content":"25.10","carb_content":"0.00","fat_content":"0.50","calories":"445.00"},{"upload_date":"2019-12-31T21:42:28.609Z","item":"hot_dog","protein_content":"10.00","carb_content":"25.00","fat_content":"15.00","calories":"1170.00"},{"upload_date":"2019-12-31T21:42:15.793Z","item":"steak","protein_content":"25.10","carb_content":"0.00","fat_content":"0.50","calories":"445.00"},{"upload_date":"2019-12-31T21:42:05.049Z","item":"greek_salad","protein_content":"6.60","carb_content":"10.30","fat_content":"19.40","calories":"1079.00"}];

const {protein, calories, carbs, fat} = dietInfo.reduce((res, entry) => ({ 
     res.protein += +entry.protein_content, // The "+" operator transforms a string containing a number to an actual number
     res.calories += +entry.calories
     res.carbs += +entry.carbs_content,
     res.fat += +entry.fat_content
}), {protein: 0, calories: 0, carbs: 0, fat: 0});

// Function to round to a specific digit or less
const roundToDigit = (num, digits) => (Math.round(num * Math.pow(10, digits) + Number.EPSILON) / Math.pow(10, digits)); 

this.protein = roundToDigit(protein, 1);
this.calories = roundToDigit(calories, 1);
this.carbs = roundToDigit(carbs, 1);
this.fat = roundToDigit(fat, 1);
pascalpuetz
  • 5,238
  • 1
  • 13
  • 26
  • This one worked basically out of the box for me. The other example although an improvement required me to make some modifications but ultimately I had some extra floating point numbers when hooked into my pie chart. Thanks @pascalpuetz – Invic18 Jan 01 '20 at 18:18