[Question]
  [
## The setup:
A social network reports the number of votes a post has in two ways: the number of **net upvotes** (total upvotes - total downvotes), and the **% of votes that were upvotes**, rounded to the nearest integer (.5 rounds up). The number of net upvotes is an integer (not necessarily positive), and the second is guaranteed to be an integer between 0 and +100 inclusive. The number of upvotes and the number of downvotes are both either zero or positive 32-bit integers (you can specify signed or unsigned). Assume that if there are zero total votes, the percentage upvoted is reported as zero.
## The challenge:
Given these two integers (net upvotes and % upvoted), what is the shortest program you can write which determines the lowest number of **total upvotes** the post received, with all the constraints above satisfied?
Input constraints are guaranteed. If the input does not satisfy the constraints above, the program behavior is up to you. Bonus kudos if it doesn't enter an infinite loop or otherwise crash. Consider returning a negative number if you want more guidance.
## General rules:
* This is [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'"), so the shortest valid solution (measured in bytes) wins.
* Don't let code-golf languages discourage you from posting answers with non-codegolfing languages. Try to come up with an as short as possible answer for 'any' programming language. Bonus kudos for a client-side Web language like Javascript.
* If you have interesting solutions in multiple languages, post them [separately](https://codegolf.meta.stackexchange.com/questions/181/multiple-answers-from-the-same-person-to-a-question).
* [Standard rules apply](https://codegolf.meta.stackexchange.com/questions/2419/default-for-code-golf-program-function-or-snippet/2422#2422) for your answer, so you are allowed to use STDIN/STDOUT, functions/method with the proper parameters and return-type, or full programs. Your call.
* [Default loopholes](https://codegolf.meta.stackexchange.com/questions/1061/loopholes-that-are-forbidden-by-default) are forbidden.
* If possible, please add a link with a test for your code.
* Also, please add an explanation of how the code works.
* Keep in mind that if you are doing an integer division operation that *truncates* (e.g. 20/3=6) rather than *rounds*, that might not be fully correct.
* Additional test cases that explore the edge cases in the above constraints are welcome.
* While the expected return type is numeric, [boolean "false" can be used in place of 0](https://codegolf.meta.stackexchange.com/a/9067/47168).
## Example test cases:
The first column is just a reference number included to facilitate discussion.
```
ref net  %up    answer
1   0    0   => 0    
2   -5   0   => 0    
3   -4   17  => 1    
4   -3   29  => 2    
5   -2   38  => 3    
6   -1   44  => 4    
7   0    50  => 1    
8   5    100 => 5    
9   4    83  => 5    
10  3    71  => 5    
11  2    63  => 5    
12  1    56  => 5    
13  1234 100 => 1234
14  800  90  => 894  (tip: don't refer to this as the "last test case;" others may be added.)
```
  
[Answer]
# JavaScript (ES6), 47 bytes
Takes input in currying syntax `(n)(p)`, where **n** is the number of net upvotes and **p** is the percentage of upvotes. [May return `false` for `0`](https://codegolf.meta.stackexchange.com/a/9067/58563).
```
n=>p=>(g=u=>u/(u-n/2)*50+.5^p?g(u+1):u)(n>0&&n)
```
[Try it online!](https://tio.run/##fc/dCoMgGIDh867Co9BF@V82sN3JIFrFRmisudtvSh2MWjsR5PnU10f9rqfmeR9fqbG3du70bHQ16gr22unKYehSgxk6SZJk8jpeeugSis4OQVORODZobqyZ7NBmg@1hBwEABMGwIIAxINGWU/mfhWdaLEz3zD2zcmG2Z@aZq4X5nqlnIRYW0c9ySY7eBr6ckpXlnkO54occygt6yKE8Pz4dymX@mynj4istbLcXKBL@Vq4TqhTzBw "JavaScript (Node.js) – Try It Online")
### Commented
```
n => p => (          // given n and p
  g = u =>           // g = recursive function taking u = number of upvotes
    u / (u - n / 2)  //   compute u / (total_votes / 2)
    * 50 + .5        //   turn it into a percentage, add 1/2
    ^ p ?            //   XOR it with p, which gives 0 if the integer parts are matching
                     //   if the result is not equal to 0:
      g(u + 1)       //     try again with u + 1
    :                //   else:
      u              //     stop recursion and return u
)(n > 0 && n)        // initial call to g() with u = max(0, n)
```
### Edge cases
Let **Fn(u) = u / (u - n / 2) \* 50 + 0.5**
* If **u = 0** and **n = 0**, then **Fn(u) = NaN** and **Fn(u) XOR p = p**. So, we return **u = 0** if **n = p = 0** (first iteration of the first test case) or continue with the recursion if **p != 0** (first iteration of the 7th test case).
* If **u > 0** and **u = n / 2**, then **Fn(u) = +Infinity** and -- again -- **Fn(u) XOR p = p**. Unless **p = 0**, we just go on with the next iteration. (This happens in the 9th and 11th test cases.)
[Answer]
# [Stax](https://github.com/tomtheisen/stax), 17 [bytes](https://github.com/tomtheisen/stax/blob/master/docs/packed.md#packed-stax)
```
ëI╩½• ╠☺Vì∞«S↑♠αS
```
[Run and debug it](https://staxlang.xyz/#p=8949caab0720cc01568decae531806e053&i=0+++0%0A-5++0%0A-4++17%0A-3++29%0A-2++38%0A-1++44%0A0+++50%0A5+++100%0A4+++83%0A3+++71%0A2+++63%0A1+++56&a=1&m=2)
This is brute force. It starts with 0 for candidate upvotes, and increments until it satisfies the formula.
Unpacked, ungolfed, and commented, it looks like this.
```
0       push zero
{       start filter block...
        candidate upvotes is on the stack
  cHx-  calculate candidate downvotes for denominator (upvotes * 2 - net)
  c1?   if denominator is zero, replace it with 1
  :_    floating point division
  AJ*   multiply by 100
  j     round to integer
  ;=    is equal to second input?
        increment until a match is found
}gs
```
[Run this one](https://staxlang.xyz/#c=0+++++%09push+zero%0A%7B+++++%09start+filter+block...%0A++++++%09candidate+upvotes+is+on+the+stack%0A++cHx-%09calculate+candidate+downvotes+for+denominator+%28upvotes+*+2+-+net%29%0A++c1%3F+%09if+denominator+is+zero,+replace+it+with+1%0A++%3A_++%09floating+point+division%0A++AJ*+%09multiply+by+100%0A++j+++%09round+to+integer%0A++%3B%3D++%09is+equal+to+second+input%3F%0A+++%09increment+until+a+match+is+found%0A%7Dgs&i=0+++0%0A-5++0%0A-4++17%0A-3++29%0A-2++38%0A-1++44%0A0+++50%0A5+++100%0A4+++83%0A3+++71%0A2+++63%0A1+++56&a=1&m=2)
[Answer]
# [Clean](https://clean.cs.ru.nl), ~~114~~ ~~107~~ 104 bytes
```
import StdEnv
? =toReal o toInt
$a d#e= ?d
= ?a+until(\c#b= ~c*e/(e-100.0)
= ?(?100*b/(?b+c))==e)inc 0.0
```
[Try it online!](https://tio.run/##FYo9C4MwFAB3f8UDHRLFquAasrSD0KmuXZ5JLIF8FH0WuvSnN02X4@BOOYMh@agPZ8CjDcn6Z9wIZtKX8CokCIo3gw4iUJwCFRWCLo0AqYsMbI5A1rG7KhcBH1Wbjpl26PtTz/@dyez10jG5NIpzIQy3QUHOaSbcqChhBQFVfldoBxjH9FWrw8ee2umazu@A3qr9Bw "Clean – Try It Online")
Defines the function `$ :: Int Int -> Real`, where the arguments are signed integers and the return value is a double-precision float exactly representable by a 32-bit signed integer.
It checks every value of `c` in the equation `b=-cd/(d+1)` to find a `b` satisfying `a+c=b` and `b/(b+c)=d`, since the smallest `c` results in the smallest `b`, take the first element of the set of all solutions.
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E), 13 bytes [mildly broken]
```
*²·т-/ò²т;Qi1
```
[Try it online!](https://tio.run/##MzBNTDJM/f9f69CmQ9svNunqH950aNPFJuvATMP//3UNuUxMAA "05AB1E – Try It Online")
Explanation:
To solve this, I assumed inputs a, b and expected result x.
Given the info in the setup, that gave me the equation:
```
 2x         100x
———— - a = ——————
 a           b
```
Rearranging for x gives
```
        ab
x = ——————————
     2b - 100
```
The only test case this doesn't work for is 0, 50 - I simply hardcoded to check for this.
```
*²·т-/ò²т;Qi1     Implicit Inputs: a, b              STACK (bottom to top)
*                 Multiply the inputs together       [ab]
 ²·               Take the second input * 2          [ab, 2b]
   т-             Subtract 100                       [ab, 2b - 100]
     /ò           Divide and round                   [round(ab/(2b-100))]
       ²т;Qi1     If 2nd input = 50, push 1 to stack
                  { Implicitly output top item of stack [either 1, or round(...)] }
```
[Answer]
# Go 1.10, 154 bytes
```
func h(n,u float64)float64{if u==50{return 1};r:=Round(n*u/(2*u-100));s:=Round(n*(u+.5)/(2*u-99));v:=s/(2*s-n);if v>1||Round(v*100)!=u{return r};return s}
```
[Try it on Go Playground!](https://play.golang.org/p/q9Ef2TyDotG) (TIO runs Go 1.9, which doesn't have math.Round)
Ungolfed version
```
func haters(n, u float64) float64 {
    if u == 50 {
        return 1
    }
    r := Round(n * u / (2*u - 100))
    //Test the case where we were given a percentage that was rounded down (e.g. 90.4% given as 90%)
    //We test this by adding 0.5% to u. The denominator is just a simplified form of 2*(u+0.5) - 100
    s := Round(n * (u + .5) / (2*u - 99))
    //Check if s is a valid result
    v := s / (2*s - n)
    if v > 1 || Round(v*100) != u {
        return r
    }
    //s is strictly less than r, so we don't need to check the minimum.
    return s
}
```
In the interests of adding an explanation, the above formula for r can be derived by simultaneously solving `n=v-d` and `u = 100 * v/(v + d)` for v, where v and d are the number of upvotes and downvotes respectively. The derived formula is undefined for v = 50, so we have to handle that case (which we do with the first if statement).
]