Most efficient/elegant way to clip a number?
What about boring, old, readable, and shortest yet:
float clip(float n, float lower, float upper) {
return std::max(lower, std::min(n, upper));
}
?
This expression could also be 'genericized' like so:
template <typename T>
T clip(const T& n, const T& lower, const T& upper) {
return std::max(lower, std::min(n, upper));
}
Update
Billy ONeal added:
Note that on windows you might have to define NOMINMAX because they define min and max macros which conflict
Most efficient way to clip a value to repeat through a range?
it is like this:
min = VALUE;
max = VALUE;
x = (((x - min) + 1) % (max - min)) + min
here x will be inside min and max - 1 when you repeat the last line of code
EDIT:
and to match your exact table:
output = (input - min) % (max - min) + min;
EDIT 2:
if modulus is not defined for negative numbers:
if (input >= min)
output = (input - min) % (max - min) + min;
else
output = max - ((max - input) % (max - min));
What's the most elegant way to cap a number to a segment?
The way you do it is pretty standard. You can define a utility clamp
function:
/**
* Returns a number whose value is limited to the given range.
*
* Example: limit the output of this computation to between 0 and 255
* (x * 255).clamp(0, 255)
*
* @param {Number} min The lower boundary of the output range
* @param {Number} max The upper boundary of the output range
* @returns A number in the range [min, max]
* @type Number
*/
Number.prototype.clamp = function(min, max) {
return Math.min(Math.max(this, min), max);
};
(Although extending language built-ins is generally frowned upon)
Fastest way to clamp a real (fixed/floating point) value?
For the 16.16 representation, the simple ternary is unlikely to be bettered speed-wise.
And for doubles, because you need it standard/portable C, bit-fiddling of any kind will end badly.
Even if a bit-fiddle was possible (which I doubt), you'd be relying on the binary representation of doubles. THIS (and their size) IS IMPLEMENTATION-DEPENDENT.
Possibly you could "guess" this using sizeof(double) and then comparing the layout of various double values against their common binary representations, but I think you're on a hiding to nothing.
The best rule is TELL THE COMPILER WHAT YOU WANT (ie ternary), and let it optimise for you.
EDIT: Humble pie time. I just tested quinmars idea (below), and it works - if you have IEEE-754 floats. This gave a speedup of about 20% on the code below. IObviously non-portable, but I think there may be a standardised way of asking your compiler if it uses IEEE754 float formats with a #IF...?
double FMIN = 3.13;
double FMAX = 300.44;
double FVAL[10] = {-100, 0.23, 1.24, 3.00, 3.5, 30.5, 50 ,100.22 ,200.22, 30000};
uint64 Lfmin = *(uint64 *)&FMIN;
uint64 Lfmax = *(uint64 *)&FMAX;
DWORD start = GetTickCount();
for (int j=0; j<10000000; ++j)
{
uint64 * pfvalue = (uint64 *)&FVAL[0];
for (int i=0; i<10; ++i)
*pfvalue++ = (*pfvalue < Lfmin) ? Lfmin : (*pfvalue > Lfmax) ? Lfmax : *pfvalue;
}
volatile DWORD hacktime = GetTickCount() - start;
for (int j=0; j<10000000; ++j)
{
double * pfvalue = &FVAL[0];
for (int i=0; i<10; ++i)
*pfvalue++ = (*pfvalue < FMIN) ? FMIN : (*pfvalue > FMAX) ? FMAX : *pfvalue;
}
volatile DWORD normaltime = GetTickCount() - (start + hacktime);
Most elegant way to clip a line?
Well, I ended up doing it myself.
For those intereseted, I ended up solving it by turning the line into a rectangle (with getBounds), then using Rectangle.intersect(clipRect,lineRect,intersectLineRect)
to create the intersection, then turning the intersection back into a line.
What is the most efficient (speed) way to get a digit from a larger number?
If int
is 32 bits, then:
static const int table[] =
{ 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 };
return number / table[position-1] % 10;
is a reasonable implementation:
- It does not invoke
pow
or use floating-point arithmetic. - It uses one table look-up, one division by a variable, and one remainder operation with a constant (which a compiler can optimize to a multiplication and some shifts and adds).
(Note that position
is adjusted in the table lookup to be one-based to match the code in the question, but common practice would be to call the units position position 0 instead of position 1.)
If digits are to be extracted for multiple positions or the whole number, then other implementations should be considered.
Most efficient way to divide a number w/ several options
You could compute the amount of leftover/waste that would come from each piece and sort it to find the minimum. Something like this?
// sample data
const lengths = [20, 24, 40, 48];
const piecesNeeded = 8;
const pieceLength = 11.75;
// how many pieces of a given length can we get from each unit of material?
const piecesPerItem = (materialLength, pieceSize) => Math.floor(materialLength / pieceSize);
// compute stats for cutting pieces
// from a given denomination of material
const computeWaste = (materialLength, pieceSize) => {
// pieces per unit of material
const perItem = piecesPerItem(materialLength, pieceSize);
// if the piece size is greater than the material size, bail
if (perItem < 1) {
return null;
}
// how many units of material would we need?
const itemsNeeded = Math.ceil(piecesNeeded / perItem);
// how much would be left over from each?
const wastePerItem = materialLength % pieceSize;
// return what we've learned
return {
perItem,
itemsNeeded,
materialLength,
wastePerItem,
totalWaste: wastePerItem * itemsNeeded
};
}
// compute the waste for each material length
const leftovers = lengths.map(length => computeWaste(length, pieceLength));
// sort by least total waste
leftovers.sort(({totalWaste: a}, {totalWaste: b}) => a - b)
// the first entry has the least total waste
console.log(leftovers[0]);
// emit all the results for inspection
console.log(leftovers);
Efficient way to code a number within a range?
You could use a mapping between value and output:
outputs = [ A, B, C, D, E, F, F, F, F, F]
output = outputs[(int)((value - 1)/ 100)]
Related Topics
Is There a Working C++ Refactoring Tool
.C VS .Cc VS. .Cpp VS .Hpp VS .H VS .Cxx
5 Years Later, Is There Something Better Than the "Fastest Possible C++ Delegates"
Compile a Dll in C/C++, Then Call It from Another Program
Std::String Length() and Size() Member Functions
Can Lambda Functions Be Templated
Visual Studio Code Formatting for "{ }"
How to Use Glortho() in Opengl
How to Navigate Through a Vector Using Iterators? (C++)
What Are Declarations and Declarators and How Are Their Types Interpreted by the Standard
What Does String::Npos Mean in This Code
Passing as Const and by Reference - Worth It
Profiling the C++ Compilation Process
C++: Where to Initialize Variables in Constructor
Is the Data in Nested Std::Arrays Guaranteed to Be Contiguous