Переведу код с c++ на javaScript и наоборот

Тема в разделе "Сделаю проект", создана пользователем Yaroslav1, 15 июл 2019.

?

Какой язык программирования вы знаете?

  1. C++

  2. JavaScript

  3. Python

  4. HTML

  5. Java

Можно выбрать сразу несколько вариантов.
Результаты будут видны только после голосования.
  1. Asper Daffy

    Asper Daffy Иксперд

    Смысл того поста (по ссылке, почитайте сначала) как раз в том, что не тратится ни одного байта памяти и ни одного такта процессора. Всё (от слова "совсем всё") вычисляется на этапе компиляции и в код попадают ТОЛЬКО готовые числовые константы.

    Это замечательная техника - можно делать вычисления любой сложности, использовать классы, наследование, шаблоны - хоть чёрта с дьяволом, но в код попадут только готовые, вычисленные литералы - "ни байта, ни такта" (разумеется вычисления делаются над данными, которые при компиляции известны) .
     
  2. SergeiL

    SergeiL Оракул Модератор

    Согласен, посмотрел код после препроцессора, не обратил внимание на "constexpr"

    Код после препроцессора:
    Код (C++):
    # 1 "test1.c"
    namespace constTimersNS {

    struct STimerParameters {
    const uint32_t maxValue;
    const int16_t * prescalers;
    const uint8_t totalPrescalers;
    };

    static constexpr uint32_t bits8 = 0x000000FFul;
    static constexpr uint32_t bits10 = 0x000003FFul;
    static constexpr uint32_t bits16 = 0x0000FFFFul;




    static constexpr int16_t prescalers01[] = { 1, 8, 64, 256, 1024 };
    static constexpr int16_t prescalers2[] = { 1, 8, 32, 64, 128, 256, 1024 };

    static constexpr STimerParameters timerParameters[] = {
    { bits8, prescalers01, sizeof(prescalers01) / sizeof(prescalers01[0]) },
    { bits16, prescalers01, sizeof(prescalers01) / sizeof(prescalers01[0]) },
    { bits8, prescalers2, sizeof(prescalers2) / sizeof(prescalers2[0]) }
    };

    constexpr int8_t totalTimers = sizeof(timerParameters) / sizeof(timerParameters[0]);

    static constexpr uint32_t getPeriod(const uint32_t frequency) {
    return (16000000L + frequency / 2) / frequency;
    }

    static constexpr uint16_t prValue(const int8_t prescalerId, const int8_t nTimer) {
    return timerParameters[nTimer].prescalers[prescalerId];
    }

    static constexpr uint32_t getDesiredTicks(const uint32_t period, const int8_t prescalerId, const int8_t nTimer) {
    return (period + prValue(prescalerId, nTimer) / 2) / prValue(prescalerId, nTimer);
    }

    static constexpr uint32_t correctTicks(uint32_t dTicks, const uint32_t maxValue) {

    return dTicks > maxValue ? maxValue : dTicks;
    }

    static constexpr uint32_t getTicks(const uint32_t period, const int8_t prescalerId, const int8_t nTimer) {
    return prescalerId >= timerParameters[nTimer].totalPrescalers ? 0x1FFFFFFF :
    correctTicks(getDesiredTicks(period, prescalerId, nTimer), timerParameters[nTimer].maxValue);
    }

    static constexpr uint32_t getBits(const int8_t prescalerId, const int8_t nTimer) {
    return prescalerId >= timerParameters[nTimer].totalPrescalers ? timerParameters[nTimer].totalPrescalers : prescalerId + 1;
    }


    static constexpr int32_t absErrorTicks(const uint32_t period, const uint32_t ticks) {
    return period > ticks ? period - ticks : ticks - period;
    }

    static constexpr int32_t absError(const uint32_t period, const int8_t prescalerId, const int8_t nTimer) {
    return prescalerId >= timerParameters[nTimer].totalPrescalers ? 0x1FFFFFFF :
    absErrorTicks(period, getTicks(period, prescalerId, nTimer) * prValue(prescalerId, nTimer));
    }

    static constexpr uint8_t getPrescalerId(const uint32_t error, const uint32_t newError, const uint8_t prId, const uint8_t candidate, const uint32_t period, const int8_t nTimer) {
    return
    (prId >= timerParameters[nTimer].totalPrescalers) ? candidate
    : getPrescalerId(newError, absError(period, prId + 1, nTimer), prId + 1, (error <= newError) ? candidate : prId, period, nTimer);
    }

    static constexpr double calcErrorPercentage(const double fcpu, const double perc) {
    return (fcpu < perc ? 1.0 - fcpu / perc : fcpu / perc - 1.0) * 100.0;
    }

    static constexpr uint16_t returnTicksOrZero(const uint32_t left, const uint32_t right, const int8_t allowableError, const uint32_t ticks) {
    return left == right || calcErrorPercentage(left, right) <= allowableError ? ticks : 0;
    }

    static constexpr uint16_t getTimerTicksIntFTicks(const uint32_t ticks, const int8_t nTimer, const uint32_t freq, uint8_t prescalerId, const int8_t allowableError) {
    return returnTicksOrZero(16000000L, freq * ticks * timerParameters[nTimer].prescalers[prescalerId], allowableError, ticks);
    }

    static constexpr uint16_t getTimerTicksIntF(const int8_t nTimer, const uint32_t freq, uint8_t prescalerId, const int8_t allowableError) {
    return getTimerTicksIntFTicks(getTicks(getPeriod(freq), prescalerId, nTimer), nTimer, freq, prescalerId, allowableError);
    }

    static constexpr uint16_t getTimerTicksIntTTicks(const uint32_t ticks, const int8_t nTimer, const uint32_t period, uint8_t prescalerId, const int8_t allowableError) {
    return returnTicksOrZero(period, ticks * timerParameters[nTimer].prescalers[prescalerId], allowableError, ticks);
    }

    static constexpr uint16_t getTimerTicksIntT(const int8_t nTimer, const uint32_t period, uint8_t prescalerId, const int8_t allowableError) {
    return getTimerTicksIntTTicks(getTicks(period, prescalerId, nTimer), nTimer, period, prescalerId, allowableError);
    }

    static constexpr int8_t __sLen(const char * str, const int8_t candidate = 0) { return (!*str) ? candidate : __sLen(str + 1, candidate + 1); }
    static constexpr bool __isFin(const char * str, const int8_t lInd) { return lInd < 0 || !isdigit(str[lInd]); }
    static constexpr uint32_t __toDig(const char * str, const uint32_t lg, const int8_t lInd) { return (str[lInd] - '0') * lg; }
    static constexpr uint32_t ___s2ul(const char * str, const uint32_t, const int8_t);
    static constexpr uint32_t __nextL(const char * str, const uint32_t lg, const int8_t lInd) { return __toDig(str, lg, lInd) + ___s2ul(str, lg * 10, lInd - 1); }
    static constexpr uint32_t ___s2ul(const char * str, const uint32_t lg, const int8_t lInd) { return __isFin(str, lInd) ? 0 : __nextL(str, lg, lInd); }
    static constexpr uint32_t __s2ul(const char * str) { return ___s2ul(str, 1, __sLen(str) - 1); }

    }

    static constexpr uint32_t operator "" _clk(const char * s) { return constTimersNS::__s2ul(s); }
    static constexpr uint32_t operator "" _us(const char * s) { return operator "" _clk(s) * (16000000L / 1000000ul); }
    static constexpr uint32_t operator "" _ms(const char * s) { return operator "" _us(s) * 1000ul; }
    static constexpr uint32_t operator "" _sec(const char * s) { return operator "" _ms(s) * 1000ul; }




    static constexpr uint8_t prescalerBitsByPeriod(const int8_t nTimer, const uint32_t period) {
    return constTimersNS::getBits(constTimersNS::getPrescalerId(0x1FFFFFul, constTimersNS::absError(period, 0, nTimer), 0, 0, period, nTimer), nTimer);
    }

    static constexpr uint16_t timerTicksByPeriod(const int8_t nTimer, const uint32_t period, const int8_t allowableError = 0) {
    return constTimersNS::getTimerTicksIntT(nTimer, period, constTimersNS::getPrescalerId(0x1FFFFFul, constTimersNS::absError(period, 0, nTimer), 0, 0, period, nTimer), allowableError);
    }

    static constexpr uint8_t prescalerBitsByFrequency(const int8_t nTimer, const uint32_t freq) {
    return prescalerBitsByPeriod(nTimer, constTimersNS::getPeriod(freq));
    }

    static constexpr uint16_t timerTicksByFrequency(const int8_t nTimer, const uint32_t freq, const int8_t allowableError = 0) {
    return constTimersNS::getTimerTicksIntF(nTimer, freq,
       constTimersNS::getPrescalerId(0x1FFFFFul, constTimersNS::absError(constTimersNS::getPeriod(freq), 0, nTimer), 0, 0,
       constTimersNS::getPeriod(freq), nTimer), allowableError);
    }

    static constexpr int16_t prescalerValue(const uint8_t nTimer, const uint8_t bits) {
    return constTimersNS::timerParameters[nTimer].prescalers[bits-1];
    }

    void setup() {
    constexpr uint8_t prescalerBits = prescalerBitsByPeriod(1, 50_ms);
    constexpr uint16_t timerTicks = timerTicksByPeriod(1, 50_ms);
    static_assert(timerTicks, "The required frequency is unattainable");
    pinMode(9, OUTPUT);
    TCCR1A = bit(COM1A0);
    TCCR1B = bit(WGM12) | prescalerBits;
    OCR1A = timerTicks;
    }

    void loop() {}
     
     
  3. Asper Daffy

    Asper Daffy Иксперд

    constexpr вычисляется после препроцессора. Посмотрите результирующий код в ассемблере. Там не будет ничего, кроме готовых числовых констант вместо prescalerBits и timerTicks
     
  4. SergeiL

    SergeiL Оракул Модератор

    Здорово, Ну не стоит прогресс на месте!
    Не было такого когда я разбирался с Си!
     
  5. Asper Daffy

    Asper Daffy Иксперд

    Чтобы это работало, надо в опциях указать -std=gnu++11 или -std=С++11 (В Ардуино это по умолчанию есть, а в AVR-Studio - нет). Но лучше не 11, а 14. Тогда в constexpr функциях можно будет нормально код писать, а то в стандарте 11-го года там в теле функции не должно быть ничего, кроме return. Я проверял, указание 14-го стандарта работает и в Студии, и в Ардуино.