1 billionth ugly or hamming number? - verification

Is this the 1 billionth ugly/hamming number?
62565096724471903888424537973014890491686968126921250076541212862080934425144389
76692222667734743108165348546009548371249535465997230641841310549077830079108427
08520497989078343041081429889246063472775181069303596625038985214292236784430583
66046734494015674435358781857279355148950650629382822451696203426871312216858487
7816068576714140173718
Does anyone have code to share that can verify this? Thanks!

This SO answer shows a code capable of calculating it.
The test entry on ideone.com takes 1.1 0.05 sec for 109 (2016-08-18: main speedup due to usage of Int instead of the default Integer where possible, even on 32-bit; additional 20% thanks to the tweak suggested by #GordonBGood, bringing band size complexity down to O(n1/3)).
It gives the answer as ((1334,335,404),"6.21607575556559E+843"), i.e.
21334 * 3335 * 5404 ≈ 6.21607575556559 * 10843.
(coincidentally, only two last digits in the fractional number above are incorrect).
This also means, of course, that there are 404 zeroes at the end of this number, and that it has 844 digits in total. So no, the number you show isn't it.

Exact answer:
6216075755565244861630816332872072003947056519089652706591632409642337022002753141824417540777256732780370172616615291935540418620025524916729500086831454711313694078635504004160312872951788703647948382456091072701600790562071797590306654765882256990391763887850141154482249915927439184562828227449023750262318234797192076792208033475638322151983772515798004125909334741121595323950448656375104457026997424772966917441779406172736975588556800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

Related

Issue with "CDbl" function while subtract values of two textboxes

I am trying to subtract the value from two textboxes in Visual Studio 2012.
Example input and results:
textbox1 - textbox2 = label1
25.9 - 25.4 = 0.50 (it's ok)
173.07 - 173 = 0.06 (should be 0.07)
144.98 - 142.12 = 2.85 (should be 2.86)
My code (I tried all three lines separately):
label1.text = (Convert.ToDouble(textbox1.text) - Convert.ToDouble(textbox2.text)).ToString
label1.text = (CDbl(textbox1.text) - CDbl(textbox2.text)).ToString
label1.text = (Val(textbox1.text) - Val(textbox2.text)).ToString
This error (may be not an error) occurs some times, not every time.
What am I missing here? And what should I use instead of "CDbl" ?
what should I use instead of "CDbl" ?
When you start with the a string, the best option is Double.Parse() or Double.TryParse(), depending on the possibility for bad data.
But even that's not enough in this case. Computers use something called IEEE754 for floating point arithmetic. This scheme for encoding floating point numbers is designed as an efficient way to represent numbers in binary, and further has direct support in CPUs for arithmetic operations, meaning it is much faster than any available alternative (it's not even close). Pretty much every programming platform uses it.
The downside is there is some loss of precision. When treated as IEEE754 doubles, 173.07-173 produces .69999999.
You can solve this in two ways:
Round the results. This isn't an option when using division, but with just addition and subtraction you can track significant digits and round to get exact results. This is a pain, though.
Use the Decimal type. Decimal isn't perfect, but is does have a much greater degree of precision (at the cost of some performance), and for your sample data produces exact results.
In short, try this code:
label1.text = (Decimal.Parse(textbox1.text) - Decimal.Parse(textbox2.text)).ToString()

Coalesce returning wrong value after a function call followed by multiplication

I have a report that presents information and I'm getting inconsistent information based on what appears to be some issue with a SQL view or possibly a SQL Function nested within the view. I've tried finding a way to debug the SQL View, however, it looks like SSMS only will debug Stored Procedures, so I'm not really sure how to step through and see what is happening. It really has me stumped and I can't help but wonder if it isn't a rounding issue.
GetItemAverageCost RETURNS DECIMAL(12,2) and the DataType in sitli.QuantityIssuedAtStockUOM is System.Int64 / bigint (sidenote: I'm confused about why LINQPad shows 2 data types for that column. In the tree on the left, after expanding the sitli table and hovering over the QuantityIssuedAtStockUOM the balloon BigInt NOT NULL pops up, but when I Take(100) and hover over the column in the result set it says System.Int64). Anyroad, here is the COALESCE function.
COALESCE((dbo.GetItemAverageCost(ItemModel.IDItemModel)*sitli.QuantityIssuedAtStockUOM) / ISNULL(NULLIF(ItemModel.UOMFactor, 0),1),0) -- 259.73
--ROUND(COALESCE((dbo.GetItemAverageCost(ItemModel.IDItemModel)*sitli.QuantityIssuedAtStockUOM) / ISNULL(NULLIF(ItemModel.UOMFactor, 0),1),0),2) -- 259.73
--COALESCE(ROUND((dbo.GetItemAverageCost(ItemModel.IDItemModel)*sitli.QuantityIssuedAtStockUOM) / ISNULL(NULLIF(ItemModel.UOMFactor,2), 0),1),0) -- 259.70
--COALESCE((ROUND(dbo.GetItemAverageCost(ItemModel.IDItemModel),2)*sitli.QuantityIssuedAtStockUOM) / ISNULL(NULLIF(ItemModel.UOMFactor, 0),1),0) -- 259.73
original / wrong coalesce:
COALESCE(dbo.GetItemAverageCost(ItemModel.IDItemModel)*sitli.QuantityIssuedAtStockUOM,0)
I'm not sure what else to include, but I haven't found many resources online that offer insight into this kind of a situation. Many thanks in advance for your time.
EDIT: GetItemAverageCost:
ALTER FUNCTION GetItemAverageCost
(
#IDItemModel varchar(8000)
)
RETURNS DECIMAL(16,4)
--RETURNS DECIMAL(12,2)
AS
BEGIN
RETURN
(
SELECT
COALESCE(AVG(poli.UnitPrice),0) as AvgCost
-- COALESCE(ROUND(AVG(poli.UnitPrice),0),2) as AvgCost 260.00
FROM ItemModel im
LEFT JOIN VendorItem vi
ON im.IDItemModel = vi.IDItemModel
JOIN POLineItem poli
ON vi.IDVendorItem = poli.IDVendorItem
WHERE
im.IDItemModel = #IDItemModel
GROUP BY
im.IDItemModel,
im.ItemNumber
)
END
To fix; have your function return 16,4 instead of 12,2 and then ROUND two two decimals after multiplying by the quantity.
"When a given report is run, there are no errors thrown. But the calculations are off. For example a part number 12 shows a quantity of 24 were issued at a cost of $259.73. However, each part costs $10.82 so the calculation should be $259.68. I'm not sure where the difference of 5 cents is coming from. The $259.73 is the result of the COALESCE function above. Hopefully this makes sense"
Run the SQL only for part 12 independent of the function and you'll see the average is 10.822083333333333333333333333333 (10.82 5/24ths)
24*unitprice = $259.73
unitprice = 259.73/24
unit price = $10.82 5/24.
You'll see the variance is $.05
10.82 5/24ths. *24 = 259.73
10.82 * 24 = 259.68
That difference of 5cents doesn't go evenly into the remaining 24. thus the rounding error when using your function.
When you think of going to the store and buying something it's always at amounts to the whole penny. When you go to the gas station they charge to the nearest .00001 cents. (or in your case 4 decimals)
The rounding when using fractions of pennies isn't done until multiplied by the quantity or when actual cash needs to change hands. If done too early you get rounding errors you are seeing.
Thus you eliminate over/under charging rounding errors and at most you'll charge a fraction of a penny less or more than you should.
Okay, so many thanks to all who helped along the way. There were a couple of issues preventing me from getting the correct answer. For one thing, I was working with the incorrect expression for much of the time. Secondly, after I figured out which expression to use, it was a matter of placing the ROUND function in the correct place.
So, the expression I should have been using to get my average cost is:
COALESCE(dbo.GetItemAverageCost(Item.IDItemModel) / ISNULL(NULLIF(UOMFactor, 0),1),0)
When I moved this into the WorkOrderItemInstructionPartCosts View, my report was then producing $10.82. Then I added *sitli.QuantityIssuedAtStockUOM to the line and was getting $259.73. Then I applied the ROUND function to the COALESCE function and voila! the correct value ($259.68) is being produced.
The final line looks like this:
ROUND(COALESCE(dbo.GetItemAverageCost(ItemModel.IDItemModel) / ISNULL(NULLIF(UOMFactor, 0),1),0),2)*sitli.QuantityIssuedAtStockUOM
Once again, thank you to all who helped me in the effort to resolve this and sorry for not having accurate information to begin with.
Best,
Jonathan

Interpretation of GAP in CPLEX

This is a part of the engine-log output that I get from a small-scale mixed integer linear optimization problem that I solved in CPLEX 12.7.0
Nodes Cuts/
Node Left Objective IInf Best Integer Best Bound ItCnt Gap
0 0 280.0338 78 280.0338 72
0 0 428.8558 28 Cuts: 89 137
0 0 429.5221 34 Cuts: 2 142
0 0 429.7745 34 MIRcuts: 2 143
* 0+ 0 460.9166 429.7745 6.76%
0 2 429.7745 34 460.9166 429.8666 143 6.74%
Elapsed time = 0.49 sec. (31.07 ticks, tree = 0.01 MB, solutions = 1)
* 35 8 integral 0 438.1448 435.6381 211 0.57%
Cover cuts applied: 17
Implied bound cuts applied: 10
Flow cuts applied: 11
Mixed integer rounding cuts applied: 9
Gomory fractional cuts applied: 24
Root node processing (before b&c):
Real time = 0.45 sec. (31.09 ticks)
Sequential b&c:
Real time = 0.08 sec. (20.80 ticks)
------------
Total (root+branch&cut) = 0.53 sec. (51.89 ticks)
What I understand from this, is that the best integer solution (for the objective function) found has the value of 438.1448, whereas the relaxed solution (non integer values) has the value of 435.6381 as best bound solution.
( 438.1448 / 435.6381 ) - 1 = 0.57% GAP
Does this mean that the solution still has that small gap, however it is proven to be the optimal solution? I had the (maybe wrong) idea that optimality is proven by a 0% gap.
I'm not sure how to interpret it correctly. Thanks for your help in advance.
Your understanding of the best bound isn't 100% correct. You can think of the best bound as the best objective value an integer solution could potentially have, based on information the solver has discovered so far. In your case there might actually be a better solution than the one you found, but if there is, it won't have an objective value better than 435.6381.
A more technical definition of the best bound is the best relaxed-but-region-constrained solution for any region that has not yet been eliminated from the search space. Solvers like CPLEX search for an optimal solution by splitting the search space into sub-regions and then ruling out sub-regions that can't possibly contain the optimal integer-feasible solution. These sub-regions get split into sub-sub-regions, and so on. Within each region, the original problem is modified to force variables to fall within the region. The relaxed solution to this modified problem is the best bound for the region. The best of these region-specific best bounds is the best bound for the problem as a whole.
The best bound changes as regions are ruled out. If the best bound does not equal the best solution, then by definition, there is still at least one region other than the region holding the current incumbent that could potentially hold a better solution. Exploring one of these regions might uncover an even better solution than your current incumbent, or it might lead to the region being ruled out. You don't know which until the region is explored. Only when the best solution equals the best bound do you know for sure that there isn't a better solution hiding in a remaining region.
Yes you are right. The optimality is proven if the upper bound and the lower bound evaluate the same value, i.e. CPLEX could prove an optimality gap of 0%.
Since CPLEX stops with a solution that has a gap of 0.57%, I would assume that you configured an MIP-gap <1%. If you are interested in a solution with proven optimal, you should change the MIPGap parameter to zero. See also here.

How does VB.NET 2008 round off integer numbers? [duplicate]

According to the documentation, the decimal.Round method uses a round-to-even algorithm which is not common for most applications. So I always end up writing a custom function to do the more natural round-half-up algorithm:
public static decimal RoundHalfUp(this decimal d, int decimals)
{
if (decimals < 0)
{
throw new ArgumentException("The decimals must be non-negative",
"decimals");
}
decimal multiplier = (decimal)Math.Pow(10, decimals);
decimal number = d * multiplier;
if (decimal.Truncate(number) < number)
{
number += 0.5m;
}
return decimal.Round(number) / multiplier;
}
Does anybody know the reason behind this framework design decision?
Is there any built-in implementation of the round-half-up algorithm into the framework? Or maybe some unmanaged Windows API?
It could be misleading for beginners that simply write decimal.Round(2.5m, 0) expecting 3 as a result but getting 2 instead.
The other answers with reasons why the Banker's algorithm (aka round half to even) is a good choice are quite correct. It does not suffer from negative or positive bias as much as the round half away from zero method over most reasonable distributions.
But the question was why .NET use Banker's actual rounding as default - and the answer is that Microsoft has followed the IEEE 754 standard. This is also mentioned in MSDN for Math.Round under Remarks.
Also note that .NET supports the alternative method specified by IEEE by providing the MidpointRounding enumeration. They could of course have provided more alternatives to solving ties, but they choose to just fulfill the IEEE standard.
Probably because it's a better algorithm. Over the course of many roundings performed, you will average out that all .5's end up rounding equally up and down. This gives better estimations of actual results if you are for instance, adding a bunch of rounded numbers. I would say that even though it isn't what some may expect, it's probably the more correct thing to do.
While I cannot answer the question of "Why did Microsoft's designers choose this as the default?", I just want to point out that an extra function is unnecessary.
Math.Round allows you to specify a MidpointRounding:
ToEven - When a number is halfway between two others, it is rounded toward the nearest even number.
AwayFromZero - When a number is halfway between two others, it is rounded toward the nearest number that is away from zero.
Decimals are mostly used for money; banker’s rounding is common when working with money. Or you could say.
It is mostly bankers that need the
decimal type; therefore it does
“banker’s rounding”
Bankers rounding have the advantage that on average you will get the same result if you:
round a set of “invoice lines” before adding them up,
or add them up then round the total
Rounding before adding up saved a lot of work in the days before computers.
(In the UK when we went decimal banks would not deal with half pence, but for many years there was still a half pence coin and shop often had prices ending in half pence – so lots of rounding)
Use another overload of Round function like this:
decimal.Round(2.5m, 0,MidpointRounding.AwayFromZero)
It will output 3. And if you use
decimal.Round(2.5m, 0,MidpointRounding.ToEven)
you will get banker's rounding.

How can I calculate pi (π) in VB?

Does anyone know how can I calculate pi (π) in VB?
System.Math.Pi
Assuming you actually want to compute pi instead of just using the built in constants, there are a bunch of ways that you can do it. Here are a few links that could be useful:
http://www.codeproject.com/KB/recipes/CRHpi.aspx
http://en.wikipedia.org/wiki/Pi#Computation_in_the_computer_age
http://en.wikipedia.org/wiki/Machin-like_formula
If you mean VB6, it doesn't have a pi constant. You can use:
Dim pi as Double
pi = 4 * Atn(1)
If the OP is asking about algorithms as a learning experience, good for him/her.
If the OP wanted help finding the built-in value, s/he has it now.
But if the goal is a good value of higher precision than the built-in value with a minimum of effort, here's pi to one million digits:
http://www.eveandersson.com/pi/digits/1000000
That should be enough.
I hope the OP isn't asking how to recalculate the value of Pi each and every time it's used. That would be madness.
Meh, so efficient, accurate and most of all boring approximations... Try this instead! Pseudocode ensues:
initialize inside and total as 0
repeat an insane amount of times:
assign both x and y random values between (and including) 0 and +1.
assign distance as the square root of (x2 + y2)
if distance ≤ 1, add 1 to inside
add 1 to total
assign pi as inside / total * 4
If you don't want to use the built in values in the .net math library...
22 / 7