3 ms·
ALways nice to see simple examples, but just going through an example, I see this: imgWidth = pow(2, log(sqrt(stat_p.st_size/3))/log(2)); And I have no clue w
by NKCSS 9y ago
ALways nice to see simple examples, but just going through an example, I see this:
imgWidth = pow(2, log(sqrt(stat_p.st_size/3))/log(2));
And I have no clue why because if you take 128 as input value; it converts it either to ~126 if you don't trunc to int before doing imgWidth * imgWidth * 3, if you truncate to int, you get 108; for what reason?
- quincunx 9y agoFrom the comments that precede it (3DPlatformer/platformer.c line 89-91), I think the idea is that the input is the size (in bytes) of the bitmap W * H * 3, where W == H and W is a power of two. So the input for a square bitmap as the comments suggest would be 128 * 128 * 3, if we unravel from there, log(x) / log(2) extracts the most significant bit, pow(2, log(x) / log(2)) sets that bit. pow(2, log(sqrt(128 * 128 * 3 / 3)) / log(2)) pow(2, log(128) / log(2)) pow(2, 7) 128 It's funny that on the one hand the code is beautifully terse enough that this ugly wart is easily discovered, yet on the other that the code would have such a wart to begin with.
- NKCSS 9y agoIf I run this in C#; it truncates to 6 and not 7... does C do an implicit round? Broken down, you get this: int toTest = 128; var div = toTest / 3; var sqrt = Math.Sqrt(div); var logSqrt = Math.Log(sqrt); var log2 = Math.Log(2); var logDiv = logSqrt / log2; var pow = Math.Pow(2, logDiv); var result = pow * pow * 3; int result2 = (int)Math.Pow(2, Math.Log(Math.Sqrt(128 / 3)) / Math.Log(2)); int total = result2 * result2 * 3; this {Clusters.DAL.Tests.UtilitiesTests} Clusters.DAL.Tests.UtilitiesTests toTest 128 int div 42 int sqrt 6.48074069840786 double logSqrt 1.8688348091416842 double log2 0.69314718055994529 double logDiv 2.6961587113893803 double pow 6.4807406984078613 double result 126.00000000000004 double result2 6 int total 108 int
- NKCSS 9y agoWouldn't this be easier to understand for newbies? [TestMethod] public void NextPowerOfTwo() { const int bitPowers = 32; const int StartValue = 2; const int PowerOf = 2; UInt32[] powers = new UInt32[bitPowers - 1]; UInt32 value = StartValue; int i = 0; powers[i++] = value; for(; i < powers.Length; i++) { value *= PowerOf; powers[i] = value; } int[] valuesToTest = new int[] { 126, 128, 130 }; int power; foreach(int valueToTest in valuesToTest) { power = 0; value = powers[power]; while(valueToTest > value) { power++; value = powers[power]; } System.Diagnostics.Debug.WriteLine($"{valueToTest} -> {value}"); } } Test Name: NextPowerOfTwo Test Outcome: Passed Result StandardOutput: Debug Trace: 126 -> 128 128 -> 128 130 -> 256
- quincunx 9y agotoTest should be 128 * 128 * 3 to reflect 128 by 128 pixels of 3 bytes each, as would be the file size. edit: just to add, I think "width = sqrt(filesize/3)" would be a better version for newbies. Even better would be to replace the code altogether.
- NKCSS 9y agoI found what was causing the off-result for me; if you do: 128 / 3 (2 int's) in C# it will truncate to int; if you do 128 / 3.0 you'll get the expected output and everything starts to make sense :)
- quincunx 9y agook, two other things that may be throwing you off, the input is a filesize, not a width, the result of filesize / 3 is always an integer (even if float representation,) and the result of sqrt(filesize/3) is also always an integer (even if float representation,) as per the comments. Also, taking the 2log and then 2power is a no-op because it doesn't truncate / ceiling in-between the two. You kind of see where the code was going to, but it never quite made it there.
- deleted 9y ago[deleted]