I'm trying to implement in log2 for integer in C++ in NaCl, I used the asm way as the nacl documentation said it's the only permitted way to write ASM, which is as follow
int log2(int x) {
int ret;
asm ( "\tbsr %1, %0\n"
: "=r"(ret)
: "r" (x)
);
return y;
}
, but turns out ARM does not support this instruction, so I want to write another version for ARM only. Is there any way to do that?
Btw, I found one solution to this particular function already, which is by using
static inline int log2(int x) {
return sizeof(int) * 8 - __builtin_clz(x) - 1;
}
mentioned in another post, so my question is purely about the way to give different implementation for different CPU Architecture. ( I've tried #ifdef ARCH_ARM, but it didn't work)
chromium native client use NACL_BUILD_ARCH to discriminate between x86, arm and mips : https://chromium.googlesource.com/chromium/chromium/+/trunk/components/nacl/nacl_defines.gypi
(NB: you can't use it if you're using PNaCl)
ex: (from here )
#elif NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 && NACL_BUILD_SUBARCH == 64
if (regs->prog_ctr >= NaClUserToSys(nap, NACL_TRAMPOLINE_START) &&
regs->prog_ctr < NaClUserToSys(nap, NACL_TRAMPOLINE_END)) {
*unwind_case = NACL_UNWIND_in_trampoline;
regs->stack_ptr += 8; /* Pop user return address */
return 1;
}
#elif NACL_ARCH(NACL_BUILD_ARCH) == NACL_arm
if (regs->prog_ctr >= NACL_TRAMPOLINE_START &&
regs->prog_ctr < NACL_TRAMPOLINE_END) {
*unwind_case = NACL_UNWIND_in_trampoline;
regs->prog_ctr = NaClSandboxCodeAddr(nap, regs->lr);
return 1;
}
#elif NACL_ARCH(NACL_BUILD_ARCH) == NACL_mips
if (regs->prog_ctr >= NACL_TRAMPOLINE_START &&
regs->prog_ctr < NACL_TRAMPOLINE_END) {
*unwind_case = NACL_UNWIND_in_trampoline;
regs->prog_ctr = NaClSandboxCodeAddr(nap, regs->return_addr);
return 1;
}
#endif
Also, bsr has an equivalent in arm if I recall correctly : http://fgiesen.wordpress.com/2013/10/18/bit-scanning-equivalencies/
Related
I've searched for a while on how to do this without any special library or anything, and it took a while to find something that's working properly.
It's possible to use
/sys/class/power_supply/BAT0/subsystem/BAT0/charge_now
/sys/class/power_supply/BAT0/subsystem/BAT0/charge_full
I was wondering, is there a better way to get the battery status using C/C++ in Ubuntu 18.04?
In case this is never answered.. this is my solution:
#define PATH_BATT_CHARGE_NOW "/sys/class/power_supply/BAT0/subsystem/BAT0/charge_now"
#define PATH_BATT_CHARGE_FULL "/sys/class/power_supply/BAT0/subsystem/BAT0/charge_full"
int getBattState(void)
{
int chargedPercent = 0;
FILE *battChargeNow;
FILE *battChargeFull;
long unsigned int battMax_mAh = 0;
long unsigned int battRemain_mAh = 0;
if (NULL == (battChargeNow = fopen(PATH_BATT_CHARGE_NOW, "r")))
{
fclose(battChargeNow);
return -1;
}
if (NULL == (battChargeFull = fopen(PATH_BATT_CHARGE_FULL, "r")))
{
fclose(battChargeNow);
fclose(battChargeFull);
return -1;
}
fscanf((FILE *)battChargeFull, "%lu", &battMax_mAh);
fscanf((FILE *)battChargeNow, "%lu", &battRemain_mAh);
chargedPercent = 100.00 * ((float)battRemain_mAh / (float)battMax_mAh);
return chargedPercent;
}
This is the code in question:
void DeckTug::StickCallback(unsigned long long evtID, DWORD value)
{
long int val = value;
if (evtID == stickXInputID || evtID == stickAxisXInputID)
stickXpct = (((double)val)) / 325.94;
else if (evtID == stickYInputID || evtID == stickAxisYInputID) {
stickYpct = (((double)val)) / 325.94;
if(isAuto)
if ((stickYpct < 0.0)) {
acPullingTug = true;
tugTBoffset = tugReversed ? towbarAttachAft * (-1.0) : towbarAttachForward;
}
else {
acPullingTug = false;
tugTBoffset = tugReversed ? towbarAttachAft * (-1.0) : towbarAttachForward;
}
}
}
When I compile a debug build, this runs perfectly. When I compile a release build, it does not work. When I attach the visual studio debugger to the release version, I can break on the first if statement and on the closing brace of the function, but I cannot hit a break point anywhere else, and neither stickXpct or stickYpct are ever being assigned anything, although in the debugger I can see that "value" has a valid value, and "evtID" DOES equal one of inputIDs.
In conclusion, it looks to me like, in the release version of the code only, both the first "if" statement and the first "else if" statement only evaluate to false, even when one of them should evaluate to true. Does anyone know what is going on here? because I don't.
Thanks so much,
Farley
Edit: changed answer in response to comments
Try adding volatility
void DeckTug::StickCallback(unsigned long long evtID, DWORD value)
{
long int val = value;
volatile unsigned long long _evtID = evtID;
if (_evtID == stickXInputID || _evtID == stickAxisXInputID)
stickXpct = (((double)val)) / 325.94;
else if (_evtID == stickYInputID || _evtID == stickAxisYInputID) {
stickYpct = (((double)val)) / 325.94;
if(isAuto)
if ((stickYpct < 0.0)) {
acPullingTug = true;
tugTBoffset = tugReversed ? towbarAttachAft * (-1.0) : towbarAttachForward;
}
else {
acPullingTug = false;
tugTBoffset = tugReversed ? towbarAttachAft * (-1.0) : towbarAttachForward;
}
}
}
That should prevent the compiler from optimizing those branches until you can track down why it wants to optimize those branches away.
I am trying to build Quantlib on VS2013 in the Release x64 mode.
I added the Boost libraries using Property Manager and then Went to solutions explorer and clicked on Build.
The final output was: Build: 18 succeeded, 1 failed. 0 up-to-date, 0 skipped.
When I double clicked on the error this file opened up (convolvedstudentt.cpp)
Copyright (C) 2014 Jose Aparicio
This file is part of QuantLib, a free-software/open-source library
for financial quantitative analysts and developers - http://quantlib.org/
QuantLib is free software: you can redistribute it and/or modify it
under the terms of the QuantLib license. You should have received a
copy of the license along with this program; if not, please email
<quantlib-dev#lists.sf.net>. The license is also available online at
<http://quantlib.org/license.shtml>.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the license for more details.
*/
#include <ql/experimental/math/convolvedstudentt.hpp>
#include <ql/errors.hpp>
#include <ql/math/factorial.hpp>
#include <ql/math/distributions/normaldistribution.hpp>
#include <ql/math/solvers1d/brent.hpp>
#include <boost/function.hpp>
#if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4))
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#endif
#include <boost/bind.hpp>
#include <boost/math/distributions/students_t.hpp>
#if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4))
#pragma GCC diagnostic pop
#endif
namespace QuantLib {
CumulativeBehrensFisher::CumulativeBehrensFisher(
const std::vector<Integer>& degreesFreedom,
const std::vector<Real>& factors
)
: degreesFreedom_(degreesFreedom), factors_(factors),
polyConvolved_(std::vector<Real>(1, 1.)), // value to start convolution
a_(0.)
{
QL_REQUIRE(degreesFreedom.size() == factors.size(),
"Incompatible sizes in convolution.");
for(Size i=0; i<degreesFreedom.size(); i++) {
QL_REQUIRE(degreesFreedom[i]%2 != 0,
"Even degree of freedom not allowed");
QL_REQUIRE(degreesFreedom[i] >= 0,
"Negative degree of freedom not allowed");
}
for(Size i=0; i<degreesFreedom_.size(); i++)
polynCharFnc_.push_back(polynCharactT((degreesFreedom[i]-1)/2));
// adjust the polynomial coefficients by the factors in the linear
// combination:
for(Size i=0; i<degreesFreedom_.size(); i++) {
Real multiplier = 1.;
for(Size k=1; k<polynCharFnc_[i].size(); k++) {
multiplier *= std::abs(factors_[i]);
polynCharFnc_[i][k] *= multiplier;
}
}
//convolution, here it is a product of polynomials and exponentials
for(Size i=0; i<polynCharFnc_.size(); i++)
polyConvolved_ =
convolveVectorPolynomials(polyConvolved_, polynCharFnc_[i]);
// trim possible zeros that might have arised:
std::vector<Real>::reverse_iterator it = polyConvolved_.rbegin();
while(it != polyConvolved_.rend()) {
if(*it == 0.) {
polyConvolved_.pop_back();
it = polyConvolved_.rbegin();
}else{
break;
}
}
// cache 'a' value (the exponent)
for(Size i=0; i<degreesFreedom_.size(); i++)
a_ += std::sqrt(static_cast<Real>(degreesFreedom_[i]))
* std::abs(factors_[i]);
a2_ = a_ * a_;
}
Disposable<std::vector<Real> >
CumulativeBehrensFisher::polynCharactT(Natural n) const {
Natural nu = 2 * n +1;
std::vector<Real> low(1,1.), high(1,1.);
high.push_back(std::sqrt(static_cast<Real>(nu)));
if(n==0) return low;
if(n==1) return high;
for(Size k=1; k<n; k++) {
std::vector<Real> recursionFactor(1,0.); // 0 coef
recursionFactor.push_back(0.); // 1 coef
recursionFactor.push_back(nu/((2.*k+1.)*(2.*k-1.))); // 2 coef
std::vector<Real> lowUp =
convolveVectorPolynomials(recursionFactor, low);
//add them up:
for(Size i=0; i<high.size(); i++)
lowUp[i] += high[i];
low = high;
high = lowUp;
}
return high;
}
Disposable<std::vector<Real> >
CumulativeBehrensFisher::convolveVectorPolynomials(
const std::vector<Real>& v1,
const std::vector<Real>& v2) const {
#if defined(QL_EXTRA_SAFETY_CHECKS)
QL_REQUIRE(!v1.empty() && !v2.empty(),
"Incorrect vectors in polynomial.");
#endif
const std::vector<Real>& shorter = v1.size() < v2.size() ? v1 : v2;
const std::vector<Real>& longer = (v1 == shorter) ? v2 : v1;
Size newDegree = v1.size()+v2.size()-2;
std::vector<Real> resultB(newDegree+1, 0.);
for(Size polyOrdr=0; polyOrdr<resultB.size(); polyOrdr++) {
for(Size i=std::max<Integer>(0, polyOrdr-longer.size()+1);
i<=std::min(polyOrdr, shorter.size()-1); i++)
resultB[polyOrdr] += shorter[i]*longer[polyOrdr-i];
}
return resultB;
}
Probability CumulativeBehrensFisher::operator()(const Real x) const {
// 1st & 0th terms with the table integration
Real integral = polyConvolved_[0] * std::atan(x/a_);
Real squared = a2_ + x*x;
Real rootsqr = std::sqrt(squared);
Real atan2xa = std::atan2(-x,a_);
if(polyConvolved_.size()>1)
integral += polyConvolved_[1] * x/squared;
for(Size exponent = 2; exponent <polyConvolved_.size(); exponent++) {
integral -= polyConvolved_[exponent] *
Factorial::get(exponent-1) * std::sin((exponent)*atan2xa)
/std::pow(rootsqr, static_cast<Real>(exponent));
}
return .5 + integral / M_PI;
}
Probability
CumulativeBehrensFisher::density(const Real x) const {
Real squared = a2_ + x*x;
Real integral = polyConvolved_[0] * a_ / squared;
Real rootsqr = std::sqrt(squared);
Real atan2xa = std::atan2(-x,a_);
for(Size exponent=1; exponent <polyConvolved_.size(); exponent++) {
integral += polyConvolved_[exponent] *
Factorial::get(exponent) * std::cos((exponent+1)*atan2xa)
/std::pow(rootsqr, static_cast<Real>(exponent+1) );
}
return integral / M_PI;
}
InverseCumulativeBehrensFisher::InverseCumulativeBehrensFisher(
const std::vector<Integer>& degreesFreedom,
const std::vector<Real>& factors,
Real accuracy)
: normSqr_(std::inner_product(factors.begin(), factors.end(),
factors.begin(), 0.)),
accuracy_(accuracy), distrib_(degreesFreedom, factors) { }
Real InverseCumulativeBehrensFisher::operator()(const Probability q) const {
Probability effectiveq;
Real sign;
// since the distrib is symmetric solve only on the right side:
if(q==0.5) {
return 0.;
}else if(q < 0.5) {
sign = -1.;
effectiveq = 1.-q;
}else{
sign = 1.;
effectiveq = q;
}
Real xMin =
InverseCumulativeNormal::standard_value(effectiveq) * normSqr_;
// inversion will fail at the Brent's bounds-check if this is not enough
// (q is very close to 1.), in a bad combination fails around 1.-1.e-7
Real xMax = 1.e6;
return sign *
Brent().solve(boost::bind(std::bind2nd(std::minus<Real>(),
effectiveq), boost::bind<Real>(
&CumulativeBehrensFisher::operator (),
distrib_, _1)), accuracy_, (xMin+xMax)/2., xMin, xMax);
}
}
The error seems to be in the third line from the bottom. That's the one that's highlighted.
effectiveq), boost::bind<Real>(
&CumulativeBehrensFisher::operator (),
distrib_, _1)), accuracy_, (xMin+xMax)/2., xMin, xMax);
When I hover a mouse over it, it says
Error: more than one instance of overloaded function "boost::bind" matches the argument list: function template "boost_bi::bind_t " etc. Please see the attached screenshot
How can I fix this? Please help.
This came up quite a few times lately on the QuantLib mailing list. In short, the code worked with Boost 1.57 (the latest version at the time of the QuantLib 1.5 release) but broke with Boost 1.58.
There's a fix for this in the QuantLib master branch on GitHub, but it hasn't made it into a release yet. If you want to (or have to) use Boost 1.58, you can check out the latest code from there. If you want to use a released QuantLib version instead, the workaround is to downgrade to Boost 1.57.
I have included file JSONValue from simpleJSON, which is used for parsing the json string.
While compiling I am getting this error that 'wcsncasecmp' was not declared in this scope.
on this line. While searching more i ot that wcsncasecmp is a GNU-specific function, I am using windows, so can anyone help me out.
else if ((simplejson_wcsnlen(*data, 4) && wcsncasecmp(*data, L"true", 4) == 0) || (simplejson_wcsnlen(*data, 5) && wcsncasecmp(*data, L"false", 5) == 0))
{
bool value = wcsncasecmp(*data, L"true", 4) == 0;
(*data) += value ? 4 : 5;
return new JSONValue(value);
}
.
I'll be greatful for any help.
On windows there is _wcsnicmp that you can use.
More ref: _strnicmp, _wcsnicmp, _mbsnicmp, _strnicmp_l, _wcsnicmp_l, _mbsnicmp_l
Please define WIN32 macro in your source or in Visual Studio please add it to the project / Properties / C/C++ / Preprocessor definition.
#define WIN32
Internally it will define wcsncasecmp as _wcsnicmp like Rohan has already mentioned.
This is a known problem of SimpleJSON.
// Win32 incompatibilities
#if defined(WIN32) && !defined(__GNUC__)
#define wcsncasecmp _wcsnicmp
static inline bool isnan(double x) { return x != x; }
static inline bool isinf(double x) { return !isnan(x) && isnan(x - x); }
#endif
I am having a field in IBM Informix database of INT8 type to hold 20 digit numbers. What should be the equivalent data type in MSVC++ (RFX equivalent data type)? I am using Visual C++ and my IDE is Visual Studio 6.0.
The field initial_amount would be declared like this:
RFX_Int64(pFX, _T("[initial_amount]"), m_initial_amount);
I have written the following custom RFX definition code for the same.
But it seems there is problem with the same.
void AFXAPI RFX_Int64(CFieldExchange* pFX, LPCTSTR szName, __int64& value)
{
ASSERT(AfxIsValidAddress(pFX, sizeof(CFieldExchange)));
ASSERT(AfxIsValidString(szName));
UINT nField;
if (!pFX->IsFieldType(&nField))
return;
LONG* plLength = pFX->m_prs->GetFieldLengthBuffer(nField - 1, pFX->m_nFieldType);
switch (pFX->m_nOperation)
{
case CFieldExchange::BindFieldToColumn:
{
#ifdef _DEBUG
// Assumes all bound fields BEFORE unbound fields
CODBCFieldInfo* pODBCInfo =
&pFX->m_prs->m_rgODBCFieldInfos[nField - 1];
if (pODBCInfo->m_nSQLType != SQL_C_DOUBLE &&
pODBCInfo->m_nSQLType != SQL_FLOAT)
{
// Warn of possible field schema mismatch
if (afxTraceFlags & traceDatabase)
TRACE1("Warning: double converted from SQL type %ld.\n",
pODBCInfo->m_nSQLType);
}
#endif
}
// fall through
default:
LDefault:
pFX->Default(szName, &value, plLength, SQL_BIGINT ,
sizeof(value), 22);
return;
case CFieldExchange::Fixup:
if (*plLength == SQL_NULL_DATA)
{
pFX->m_prs->SetNullFieldStatus(nField - 1);
value = afxDoublePseudoNull;
}
return;
case CFieldExchange::SetFieldNull:
if ((pFX->m_pvField == NULL &&
pFX->m_nFieldType == CFieldExchange::outputColumn) ||
pFX->m_pvField == &value)
{
if (pFX->m_bField)
{
pFX->m_prs->SetNullFieldStatus(nField - 1);
value = afxDoublePseudoNull;
*plLength = SQL_NULL_DATA;
}
else
{
pFX->m_prs->ClearNullFieldStatus(nField - 1);
*plLength = sizeof(value);
}
#ifdef _DEBUG
pFX->m_nFieldFound = nField;
#endif
}
return;
case CFieldExchange::MarkForAddNew:
// can force writing of psuedo-null value (as a non-null) by setting field dirty
if (value != afxDoublePseudoNull)
{
pFX->m_prs->SetDirtyFieldStatus(nField - 1);
pFX->m_prs->ClearNullFieldStatus(nField - 1);
}
return;
case CFieldExchange::MarkForUpdate:
if (value != afxDoublePseudoNull)
pFX->m_prs->ClearNullFieldStatus(nField - 1);
goto LDefault;
case CFieldExchange::AllocCache:
{
CFieldInfo* pInfo = &pFX->m_prs->m_rgFieldInfos[nField - 1];
pInfo->m_pvDataCache = new __int64;
pInfo->m_nDataType = AFX_RFX_DOUBLE;
}
return;
#ifdef _DEBUG
// case CFieldExchange::DumpField:
// {
// *pFX->m_pdcDump << "\n" << szName << " = " << value;
// }
return;
#endif //_DEBUG
}
}
Will this code work for Visual C++ 6.0 ? If not, then how should I go about?
You can only get 19 digits stored in an INT8, not 20. If you need 20 digits, use a DECIMAL(20,0).
You should use BIGINT rather than INT8; BIGINT occupies 8 bytes on disk whereas INT8 occupies 10 bytes on disk (don't ask).
How does this differ from your previous two questions on RFX and 64-bit integers?
RFX_BigInt Error.
RFX Equivalent Data Type for __int64 in Informix.
As for what's possible in MS Visual C++ 6.0, I'm sorry, I have no idea. Wikipedia says it was released in 1998; that's a little old, isn't it? The chances are it does not support 64-bit data types, which could well be why you are having problems with 64-bit data types when using it.