У Лагранжа и Коши
Члены очень хороши.
А у Шлёмильха и Роша
Самый, говорят, хороший.
// write Intel word
void st::Stream::writeIW(uint16_t w)
{
write(&w, sizeof(uint16_t));
}
Утилита не часть интерфейса, и лучший синтаксис для утилит — методы-расширители C#. На худой конец подойдёт простая функция типа Streams.writeIW(stream, 10);
.// Возвращает остаток потока
// cu_minus = clipped unsigned minus
virtual Pos remainder() { return cu_minus<Pos>(size(),pos()); }
Если в языке нет штатных реализаций, строят класс, где эти функции чем-то реализованы — не всегда, но часто можно унаследоваться от этого класса.class IC { // interface
public:
virtual int getC() = 0;
virtual ~IC() = default;
};
class C : public IC {
public:
int getC() final { return 42; }
};
class B {
public:
IC* buddy() const { return fBuddy; }
void setBuddy(IC* aBuddy) { fBuddy = aBuddy; }
void someJob() const { if (fBuddy) std::cout << fBuddy->getC() << std::endl; }
private:
IC* fBuddy = nullptr;
};
class A {
public:
A() { b.setBuddy(&c); }
private:
C c;
B b;
}
a >= b && a >= c && c <= b
второе не нужно. Можно просто писать: c <= b && b <= a
.if (a >= b) {
// куча сравнений
} else {
// ещё одна куча
}
enum {
DOUBLE_MANTISSA_BITS = 52,
DOUBLE_MIN_EXPONENT = -1022,
DOUBLE_EXPONENT_BIAS = 1023,
};
#define UC8x(X,Y,Z,T) (static_cast<uint64_t>(0x##X##Y##Z##T##ULL))
#define DOUBLE_MANTISSA_MASK UC8x(000f, ffff, ffff, ffff)
#define DOUBLE_EXPONENT_MASK UC8x(7ff0, 0000, 0000, 0000)
#define DOUBLE_EXPONENT_MASK_HI UC4x(7ff0, 0000)
#define DOUBLE_IMPLICIT_BIT (DOUBLE_MANTISSA_MASK + 1)
union DoubleInt {
double asDouble;
uint64_t asInt;
struct {
uint32_t lo, hi;
} asIntel;
....
}
int DoubleInt::exponent() const
{
return static_cast<int>((
static_cast<int64_t>(asInt & DOUBLE_EXPONENT_MASK) >>
(DOUBLE_MANTISSA_BITS)) - DOUBLE_EXPONENT_BIAS);
}
uint64_t DoubleInt::unsafeMantissa() const
{
int ex = exponent();
uint64_t bits = asInt & DOUBLE_MANTISSA_MASK;
return (ex == DOUBLE_MIN_EXPONENT - 1)
? bits << 1
: bits | DOUBLE_IMPLICIT_BIT;
}
bool DoubleInt::isPreciseInteger() const
{
// функцию isFinite() намеренно упустил, ибо она есть «в коробке» Delphi.
// А вот в Си++ есть не во всех реализациях…
return isFinite()
&& (asDouble == 0.0 ||
DOUBLE_MANTISSA_BITS - numberOfTrailingZeros(unsafeMantissa()) <= exponent());
}
int math::numberOfTrailingZeros(uint64_t i)
{
uint32_t x, y;
if (i == 0u) return 64;
int n = 63;
y = static_cast<uint32_t>(i);
if (y != 0) { n = n -32; x = y; } else x = (int)(i >> 32);
y = x << 16; if (y != 0) { n = n -16; x = y; }
y = x << 8; if (y != 0) { n = n - 8; x = y; }
y = x << 4; if (y != 0) { n = n - 4; x = y; }
y = x << 2; if (y != 0) { n = n - 2; x = y; }
return n - ((x << 1) >> 31);
}
bool math::isPreciseInteger(double x)
{
DoubleInt di;
di.asDouble = x;
return di.isPreciseInteger();
}
const int FIBONACCI_TABLE[] = { 0, 1, 1, 2, 3, 5, 8, 13 };
void sayHello(const std::string& name);
void sayHello(const char* name);
float oneAndHalf = 1.5f;
int one = oneAndHalf; // 1
int(1.5)
, преобразование как в Си (int)1.5
и ключевое слово static_cast static_cast<int>(1.5)
. std::string command;
char data1 = 'F';
char data2 = 'C';
command = std::string("color ") + data1 + data2;
system(command.c_str());