Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix cpm floor issue in price bucket formula #2644

Merged
merged 4 commits into from
May 31, 2018

Conversation

jsnellbaker
Copy link
Collaborator

@jsnellbaker jsnellbaker commented May 29, 2018

Type of change

  • Bugfix

Description of change

To fix the issue reported in #2350

Summary of issue/change (taken from thread in that issue):
The issue appears to be how dividing with decimals is handed in JavaScript. For example, when you divide 4.01 / 0.01 in a calculator you would get 401. However if you do the same thing in JavaScript (easily see this in the browser console), you get 400.99999999999994. There are numerous sets of values that result in this manner, either slightly higher or lower than the expected mark (eg 1.11 / .01 = 111.00000000000001).

When the Math.floor gets applied to these low rogue values, it'll reduce it down one level below it's expected value. So 400.99999999999994 becomes 400, which is how we ultimately see a 4.01 cpm end up in the 4.00 cpm bucket when we have 0.01 increments.

I've found an adjustment to the formula that appears to work. We multiply the individual values of the formula that gets floored (ie (cpm - bucketPrice) / increment by exponential base of 10 (eg 100000) to avoid doing the math with decimals which avoids any rounding issues.

update - we switched to this alternate logic as it was seen to be more efficient than the previous precision-rounding solution. See https://jsperf.com/cpm-bucket-rounding/ to the unit test comparison.

// force to 10 decimal places to deal with imprecise decimal/binary conversions
// (for example 0.1 * 3 = 0.30000000000000004)
cpmTarget = Number(cpmTarget.toFixed(10));
return cpmTarget.toFixed(precision);
}

function round(number, precision) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should link the source for this function.

@mkendall07 mkendall07 added LGTM needs 2nd review Core module updates require two approvals from the core team labels May 30, 2018
@snapwich snapwich self-requested a review May 31, 2018 00:17
Copy link
Collaborator

@snapwich snapwich left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@jaiminpanchal27 jaiminpanchal27 merged commit a417697 into master May 31, 2018
Pupis pushed a commit to adform/Prebid.js that referenced this pull request Jun 7, 2018
* fix cpm rounding issue in price bucket formula

* switch logic to exponent variant instead of precision rounding

*  update min precision to 2 for exponent

* fixed addition
dluxemburg pushed a commit to Genius/Prebid.js that referenced this pull request Jul 17, 2018
* fix cpm rounding issue in price bucket formula

* switch logic to exponent variant instead of precision rounding

*  update min precision to 2 for exponent

* fixed addition
@mkendall07 mkendall07 deleted the bugfix/price_gran_rounding branch August 17, 2018 15:11
ghost pushed a commit to devunrulymedia/Prebid.js that referenced this pull request Jan 30, 2019
* fix cpm rounding issue in price bucket formula

* switch logic to exponent variant instead of precision rounding

*  update min precision to 2 for exponent

* fixed addition
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
LGTM needs 2nd review Core module updates require two approvals from the core team
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants