mirror of
https://github.com/oliverbooth/X10D
synced 2024-11-23 00:58:48 +00:00
Add RoundUpToPowerOf2
This commit is contained in:
parent
5aea71465a
commit
683e02cc2a
@ -2,6 +2,7 @@
|
||||
|
||||
## 3.2.0
|
||||
### Added
|
||||
- X10D: Added `RoundUpToPowerOf2()` for built-in integer types
|
||||
- X10D: Added `Vector2.Deconstruct()`
|
||||
- X10D: Added `Vector3.Deconstruct()`
|
||||
- X10D: Added `Vector4.Deconstruct()`
|
||||
|
@ -39,4 +39,29 @@ public class ByteTests
|
||||
const byte value = 181; // 10110101
|
||||
Assert.AreEqual(value, value.RotateRight(8));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void RoundUpToPowerOf2_ShouldReturnRoundedValue_GivenValue()
|
||||
{
|
||||
Assert.AreEqual(4, ((byte)3).RoundUpToPowerOf2());
|
||||
Assert.AreEqual(8, ((byte)5).RoundUpToPowerOf2());
|
||||
Assert.AreEqual(8, ((byte)6).RoundUpToPowerOf2());
|
||||
Assert.AreEqual(8, ((byte)7).RoundUpToPowerOf2());
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void RoundUpToPowerOf2_ShouldReturnSameValue_GivenPowerOf2()
|
||||
{
|
||||
for (var i = 0; i < 8; i++)
|
||||
{
|
||||
var value = (byte)System.Math.Pow(2, i);
|
||||
Assert.AreEqual(value, value.RoundUpToPowerOf2());
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void RoundUpToPowerOf2_ShouldReturn0_Given0()
|
||||
{
|
||||
Assert.AreEqual(0, ((byte)0).RoundUpToPowerOf2());
|
||||
}
|
||||
}
|
||||
|
@ -41,4 +41,29 @@ public class Int16Tests
|
||||
const short value = 2896; // 00001011 01010000
|
||||
Assert.AreEqual(value, value.RotateRight(16));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void RoundUpToPowerOf2_ShouldReturnRoundedValue_GivenValue()
|
||||
{
|
||||
Assert.AreEqual(4, ((short)3).RoundUpToPowerOf2());
|
||||
Assert.AreEqual(8, ((short)5).RoundUpToPowerOf2());
|
||||
Assert.AreEqual(8, ((short)6).RoundUpToPowerOf2());
|
||||
Assert.AreEqual(8, ((short)7).RoundUpToPowerOf2());
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void RoundUpToPowerOf2_ShouldReturnSameValue_GivenPowerOf2()
|
||||
{
|
||||
for (var i = 0; i < 8; i++)
|
||||
{
|
||||
var value = (short) System.Math.Pow(2, i);
|
||||
Assert.AreEqual(value, value.RoundUpToPowerOf2());
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void RoundUpToPowerOf2_ShouldReturn0_Given0()
|
||||
{
|
||||
Assert.AreEqual(0, ((short)0).RoundUpToPowerOf2());
|
||||
}
|
||||
}
|
||||
|
@ -39,4 +39,29 @@ public class Int32Tests
|
||||
const int value = 284719; // 00000000 00000100 01011000 00101111
|
||||
Assert.AreEqual(value, value.RotateRight(32));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void RoundUpToPowerOf2_ShouldReturnRoundedValue_GivenValue()
|
||||
{
|
||||
Assert.AreEqual(4, 3.RoundUpToPowerOf2());
|
||||
Assert.AreEqual(8, 5.RoundUpToPowerOf2());
|
||||
Assert.AreEqual(8, 6.RoundUpToPowerOf2());
|
||||
Assert.AreEqual(8, 7.RoundUpToPowerOf2());
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void RoundUpToPowerOf2_ShouldReturnSameValue_GivenPowerOf2()
|
||||
{
|
||||
for (var i = 0; i < 8; i++)
|
||||
{
|
||||
var value = (int)System.Math.Pow(2, i);
|
||||
Assert.AreEqual(value, value.RoundUpToPowerOf2());
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void RoundUpToPowerOf2_ShouldReturn0_Given0()
|
||||
{
|
||||
Assert.AreEqual(0, 0.RoundUpToPowerOf2());
|
||||
}
|
||||
}
|
||||
|
@ -39,4 +39,29 @@ public class Int64Tests
|
||||
const long value = 5972019251303316844; // 01010010 11100000 11011111 11011110 00110001 10111010 01111101 01101100
|
||||
Assert.AreEqual(value, value.RotateRight(64));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void RoundUpToPowerOf2_ShouldReturnRoundedValue_GivenValue()
|
||||
{
|
||||
Assert.AreEqual(4L, 3L.RoundUpToPowerOf2());
|
||||
Assert.AreEqual(8L, 5L.RoundUpToPowerOf2());
|
||||
Assert.AreEqual(8L, 6L.RoundUpToPowerOf2());
|
||||
Assert.AreEqual(8L, 7L.RoundUpToPowerOf2());
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void RoundUpToPowerOf2_ShouldReturnSameValue_GivenPowerOf2()
|
||||
{
|
||||
for (var i = 0; i < 8; i++)
|
||||
{
|
||||
var value = (long)System.Math.Pow(2, i);
|
||||
Assert.AreEqual(value, value.RoundUpToPowerOf2());
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void RoundUpToPowerOf2_ShouldReturn0_Given0()
|
||||
{
|
||||
Assert.AreEqual(0L, 0L.RoundUpToPowerOf2());
|
||||
}
|
||||
}
|
||||
|
@ -40,4 +40,29 @@ public class SByteTests
|
||||
const sbyte value = 117; // 01110101
|
||||
Assert.AreEqual(value, value.RotateRight(8));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void RoundUpToPowerOf2_ShouldReturnRoundedValue_GivenValue()
|
||||
{
|
||||
Assert.AreEqual(4, ((sbyte)3).RoundUpToPowerOf2());
|
||||
Assert.AreEqual(8, ((sbyte)5).RoundUpToPowerOf2());
|
||||
Assert.AreEqual(8, ((sbyte)6).RoundUpToPowerOf2());
|
||||
Assert.AreEqual(8, ((sbyte)7).RoundUpToPowerOf2());
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void RoundUpToPowerOf2_ShouldReturnSameValue_GivenPowerOf2()
|
||||
{
|
||||
for (var i = 0; i < 7; i++)
|
||||
{
|
||||
var value = (sbyte)System.Math.Pow(2, i);
|
||||
Assert.AreEqual(value, value.RoundUpToPowerOf2());
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void RoundUpToPowerOf2_ShouldReturn0_Given0()
|
||||
{
|
||||
Assert.AreEqual(0, ((sbyte)0).RoundUpToPowerOf2());
|
||||
}
|
||||
}
|
||||
|
@ -42,4 +42,29 @@ public class UInt16Tests
|
||||
const ushort value = 2896; // 00001011 01010000
|
||||
Assert.AreEqual(value, value.RotateRight(16));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void RoundUpToPowerOf2_ShouldReturnRoundedValue_GivenValue()
|
||||
{
|
||||
Assert.AreEqual(4U, ((ushort)3).RoundUpToPowerOf2());
|
||||
Assert.AreEqual(8U, ((ushort)5).RoundUpToPowerOf2());
|
||||
Assert.AreEqual(8U, ((ushort)6).RoundUpToPowerOf2());
|
||||
Assert.AreEqual(8U, ((ushort)7).RoundUpToPowerOf2());
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void RoundUpToPowerOf2_ShouldReturnSameValue_GivenPowerOf2()
|
||||
{
|
||||
for (var i = 0; i < 8; i++)
|
||||
{
|
||||
var value = (ushort)System.Math.Pow(2, i);
|
||||
Assert.AreEqual(value, value.RoundUpToPowerOf2());
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void RoundUpToPowerOf2_ShouldReturn0_Given0()
|
||||
{
|
||||
Assert.AreEqual(0U, ((ushort)0).RoundUpToPowerOf2());
|
||||
}
|
||||
}
|
||||
|
@ -39,5 +39,28 @@ public class UInt32Tests
|
||||
{
|
||||
const uint value = 284719; // 00000000 00000100 01011000 00101111
|
||||
Assert.AreEqual(value, value.RotateRight(32));
|
||||
} [TestMethod]
|
||||
public void RoundUpToPowerOf2_ShouldReturnRoundedValue_GivenValue()
|
||||
{
|
||||
Assert.AreEqual(4U, 3U.RoundUpToPowerOf2());
|
||||
Assert.AreEqual(8U, 5U.RoundUpToPowerOf2());
|
||||
Assert.AreEqual(8U, 6U.RoundUpToPowerOf2());
|
||||
Assert.AreEqual(8U, 7U.RoundUpToPowerOf2());
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void RoundUpToPowerOf2_ShouldReturnSameValue_GivenPowerOf2()
|
||||
{
|
||||
for (var i = 0; i < 8; i++)
|
||||
{
|
||||
var value = (uint)System.Math.Pow(2, i);
|
||||
Assert.AreEqual(value, value.RoundUpToPowerOf2());
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void RoundUpToPowerOf2_ShouldReturn0_Given0()
|
||||
{
|
||||
Assert.AreEqual(0U, 0U.RoundUpToPowerOf2());
|
||||
}
|
||||
}
|
||||
|
@ -40,4 +40,29 @@ public class UInt64Tests
|
||||
const ulong value = 5972019251303316844; // 01010010 11100000 11011111 11011110 00110001 10111010 01111101 01101100
|
||||
Assert.AreEqual(value, value.RotateRight(64));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void RoundUpToPowerOf2_ShouldReturnRoundedValue_GivenValue()
|
||||
{
|
||||
Assert.AreEqual(4UL, 3UL.RoundUpToPowerOf2());
|
||||
Assert.AreEqual(8UL, 5UL.RoundUpToPowerOf2());
|
||||
Assert.AreEqual(8UL, 6UL.RoundUpToPowerOf2());
|
||||
Assert.AreEqual(8UL, 7UL.RoundUpToPowerOf2());
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void RoundUpToPowerOf2_ShouldReturnSameValue_GivenPowerOf2()
|
||||
{
|
||||
for (var i = 0; i < 8; i++)
|
||||
{
|
||||
var value = (ulong)System.Math.Pow(2, i);
|
||||
Assert.AreEqual(value, value.RoundUpToPowerOf2());
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void RoundUpToPowerOf2_ShouldReturn0_Given0()
|
||||
{
|
||||
Assert.AreEqual(0UL, 0UL.RoundUpToPowerOf2());
|
||||
}
|
||||
}
|
||||
|
@ -48,4 +48,23 @@ public static class ByteExtensions
|
||||
count = count.Mod(8);
|
||||
return (byte)((value >> count) | (value << (8 - count)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rounds the current value up to a power of two.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to round.</param>
|
||||
/// <returns>
|
||||
/// The smallest power of two that's greater than or equal to <paramref name="value" />, or 0 if <paramref name="value" />
|
||||
/// is 0 or the result overflows.
|
||||
/// </returns>
|
||||
[Pure]
|
||||
#if NETSTANDARD2_1
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#else
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||
#endif
|
||||
public static byte RoundUpToPowerOf2(this byte value)
|
||||
{
|
||||
return (byte)((uint)value).RoundUpToPowerOf2();
|
||||
}
|
||||
}
|
||||
|
@ -47,4 +47,23 @@ public static class Int16Extensions
|
||||
var unsigned = unchecked((ushort)value);
|
||||
return unchecked((short)unsigned.RotateRight(count));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rounds the current value up to a power of two.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to round.</param>
|
||||
/// <returns>
|
||||
/// The smallest power of two that's greater than or equal to <paramref name="value" />, or 0 if <paramref name="value" />
|
||||
/// is 0 or the result overflows.
|
||||
/// </returns>
|
||||
[Pure]
|
||||
#if NETSTANDARD2_1
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#else
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||
#endif
|
||||
public static short RoundUpToPowerOf2(this short value)
|
||||
{
|
||||
return (short)((uint)value).RoundUpToPowerOf2();
|
||||
}
|
||||
}
|
||||
|
@ -47,4 +47,23 @@ public static class Int32Extensions
|
||||
var unsigned = unchecked((uint)value);
|
||||
return unchecked((int)unsigned.RotateRight(count));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rounds the current value up to a power of two.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to round.</param>
|
||||
/// <returns>
|
||||
/// The smallest power of two that's greater than or equal to <paramref name="value" />, or 0 if <paramref name="value" />
|
||||
/// is 0 or the result overflows.
|
||||
/// </returns>
|
||||
[Pure]
|
||||
#if NETSTANDARD2_1
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#else
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||
#endif
|
||||
public static int RoundUpToPowerOf2(this int value)
|
||||
{
|
||||
return (int)((uint)value).RoundUpToPowerOf2();
|
||||
}
|
||||
}
|
||||
|
@ -47,4 +47,23 @@ public static class Int64Extensions
|
||||
var unsigned = unchecked((ulong)value);
|
||||
return unchecked((long)unsigned.RotateRight(count));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rounds the current value up to a power of two.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to round.</param>
|
||||
/// <returns>
|
||||
/// The smallest power of two that's greater than or equal to <paramref name="value" />, or 0 if <paramref name="value" />
|
||||
/// is 0 or the result overflows.
|
||||
/// </returns>
|
||||
[Pure]
|
||||
#if NETSTANDARD2_1
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#else
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||
#endif
|
||||
public static long RoundUpToPowerOf2(this long value)
|
||||
{
|
||||
return (long)((ulong)value).RoundUpToPowerOf2();
|
||||
}
|
||||
}
|
||||
|
@ -48,4 +48,23 @@ public static class SByteExtensions
|
||||
var signed = unchecked((byte)value);
|
||||
return unchecked((sbyte)signed.RotateRight(count));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rounds the current value up to a power of two.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to round.</param>
|
||||
/// <returns>
|
||||
/// The smallest power of two that's greater than or equal to <paramref name="value" />, or 0 if <paramref name="value" />
|
||||
/// is 0 or the result overflows.
|
||||
/// </returns>
|
||||
[Pure]
|
||||
#if NETSTANDARD2_1
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#else
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||
#endif
|
||||
public static sbyte RoundUpToPowerOf2(this sbyte value)
|
||||
{
|
||||
return (sbyte)((uint)value).RoundUpToPowerOf2();
|
||||
}
|
||||
}
|
||||
|
@ -46,4 +46,23 @@ public static class UInt16Extensions
|
||||
{
|
||||
return (ushort)((ushort)(value >> count) | (ushort)(value << (16 - count)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rounds the current value up to a power of two.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to round.</param>
|
||||
/// <returns>
|
||||
/// The smallest power of two that's greater than or equal to <paramref name="value" />, or 0 if <paramref name="value" />
|
||||
/// is 0 or the result overflows.
|
||||
/// </returns>
|
||||
[Pure]
|
||||
#if NETSTANDARD2_1
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#else
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||
#endif
|
||||
public static ushort RoundUpToPowerOf2(this ushort value)
|
||||
{
|
||||
return (ushort)((uint)value).RoundUpToPowerOf2();
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System.Diagnostics.Contracts;
|
||||
using System.Numerics;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace X10D.Numerics;
|
||||
@ -46,4 +47,34 @@ public static class UInt32Extensions
|
||||
{
|
||||
return (value >> count) | (value << (32 - count));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rounds the current value up to a power of two.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to round.</param>
|
||||
/// <returns>
|
||||
/// The smallest power of two that's greater than or equal to <paramref name="value" />, or 0 if <paramref name="value" />
|
||||
/// is 0 or the result overflows.
|
||||
/// </returns>
|
||||
[Pure]
|
||||
#if NETSTANDARD2_1
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#else
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||
#endif
|
||||
public static uint RoundUpToPowerOf2(this uint value)
|
||||
{
|
||||
#if NET6_0_OR_GREATER
|
||||
return BitOperations.RoundUpToPowerOf2(value);
|
||||
#else
|
||||
// Based on https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
|
||||
--value;
|
||||
value |= value >> 1;
|
||||
value |= value >> 2;
|
||||
value |= value >> 4;
|
||||
value |= value >> 8;
|
||||
value |= value >> 16;
|
||||
return value + 1;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System.Diagnostics.Contracts;
|
||||
using System.Numerics;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace X10D.Numerics;
|
||||
@ -46,4 +47,35 @@ public static class UInt64Extensions
|
||||
{
|
||||
return (value >> count) | (value << (64 - count));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rounds the current value up to a power of two.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to round.</param>
|
||||
/// <returns>
|
||||
/// The smallest power of two that's greater than or equal to <paramref name="value" />, or 0 if <paramref name="value" />
|
||||
/// is 0 or the result overflows.
|
||||
/// </returns>
|
||||
[Pure]
|
||||
#if NETSTANDARD2_1
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#else
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||
#endif
|
||||
public static ulong RoundUpToPowerOf2(this ulong value)
|
||||
{
|
||||
#if NET6_0_OR_GREATER
|
||||
return BitOperations.RoundUpToPowerOf2(value);
|
||||
#else
|
||||
// Based on https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
|
||||
--value;
|
||||
value |= value >> 1;
|
||||
value |= value >> 2;
|
||||
value |= value >> 4;
|
||||
value |= value >> 8;
|
||||
value |= value >> 16;
|
||||
value |= value >> 32;
|
||||
return value + 1;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user