#include <iostream>
#include <vector>
#include <string>
// radix-10 arbitrary size integer class
template<typename T>
class HugInt {
// integer digits are stored in a Vector container
// The example uses the class Vector, derived (statically)
// from std::vector<T> in order to mimic the class from
// code in the Question. Normally, I would just use a std::vector.
class Vector : public std::vector<T> { // virtual never needed
public:
int getSize() const {
return static_cast<int>(std::vector<T>::size());
} };
// two member variables
Vector integer;
int sign;
// For encapsulation and compactness, this class uses a lot
// of inline-friend functions. If considering using your own
// inline-friends, it must always be called passing at least one
// object from the class where the function is defined.
// Otherwise, the compiler cannot find it.
// compares just the magnitude (unsigned) parts of two HugInts
// returns a>b:1, a==b:0, a<b:-1
friend int cmpMagnitude(const HugInt& lh, const HugInt& rh) {
const int lh_size = lh.integer.getSize();
const int rh_size = rh.integer.getSize();
if(lh_size != rh_size) return lh_size > rh_size ? 1 : -1;
for(int i=lh_size-1; i+1; --i) {
if(lh.integer[i] != rh.integer[i]) {
return lh.integer[i] > rh.integer[i] ? 1 : -1;
} }
return 0;
}
// subtract the magnitude of op2 from the magnitude of *this
// does not take signs into account, but
// flips sign of *this if op2 has a greater magnitude than *this
void subMagnitude(const HugInt& op2) {
const int cm = cmpMagnitude(*this, op2);
if(cm == 0) {
// magnitudes are equal, so result is zero
integer.clear();
sign = 0;
return;
}
if(cm < 0) {
// If op2's magnitude is greater than this's
// subtract this's Magnitude from op2's,
// then set this to the negated result
HugInt temp{op2};
temp.subMagnitude(*this);
integer = temp.integer;
sign = -sign;
return;
}
// perform digit-wise Magnitude subtraction
// here, this's Magnitude is always greater or
// equal to op2's
T borrow = 0;
const int min_size = op2.integer.getSize();
int i;
for(i=0; i<min_size; ++i) {
const T s = op2.integer[i] + borrow;
if(borrow = (integer[i] < s)) {
integer[i] += T(10);
}
integer[i] -= s;
}
// propagate borrow to upper words (beyond op2's size)
// i is guaranteed to stay in bounds
while(borrow) {
if(borrow = (integer[i] < 1)) {
integer[i] += T(10);
}
--integer[i++];
}
// remove zeroes at end until a nonzero
// digit is encountered or the vector is empty
while(!integer.empty() && !integer.back()) {
integer.pop_back();
}
// if the vector is empty after removing zeroes,
// the object's value is 0, fixup the sign
if(integer.empty()) sign = 0;
}
void addMagnitude(const HugInt& op2) {
std::cout << "addMagnitude called but not implemented\n";
}
// get_sign generically gets a value's sign as an int
template <typename D>
static int get_sign(const D& x) { return int(x > 0) - (x < 0); }
public:
HugInt() : sign(0) {} // Default ctor
// Conversion ctor for template type
// Handles converting from any type not handled elsewhere
// Assumes D is some kind of integer type
// To be more correct, narrow the set of types this overload will handle,
// either by replacing with overloads for specific types,
// or use <type_traits> to restrict it to integer types.
template <typename D>
HugInt(D src) : sign(get_sign(src)) {
// if src is negative, make absolute value to store magnitude in Vector
if(sign < 0) src = D(0)-src; // subtract from zero prevents warning with unsigned D
// loop gets digits from least- to most-significant
// Repeat until src is zero: get the low digit, with src (mod 10)
// then divide src by 10 to shift all digits down one place.
while(src >= 1) {
integer.push_back(T(src % D(10)));
src /= D(10);
} }
// converting floating-point values will cause an error if used with the integer modulo
// operator (%). New overloads could use fmod. But for a shorter example, do something cheesy:
HugInt(double src) : HugInt(static_cast<long long>(src)) {}
HugInt(float src) : HugInt(static_cast<long long>(src)) {}
// conversion ctor from std::string
HugInt(const std::string& str) : sign(1) {
for(auto c : str) {
switch(c) {
// for simple, short parsing logic, a '-'
// found anywhere in the parsed value will
// negate the sign. If the '-' count is even,
// the result will be positive.
case '-': sign = -sign; break;
case '+': case ' ': case '\t': break; // '+', space and tab ignored
case '0': if(integer.empty()) break; // ignore leading zeroes or fallthrough
case '1': case '2': case '3': case '4': case '5':
case '6': case '7': case '8': case '9':
integer.insert(integer.begin(), T(c - '0'));
break;
} }
if(integer.empty()) sign = 0; // fix up zero value if no digits between '1' and '9' found
}
// conversion ctor from C-String (dispatches to std::string ctor)
HugInt(const char* str) : HugInt(std::string(str)) {}
// The default behavior, using value semantics to copy the
// two data members, is correct for our copy/move ctors/assigns
HugInt(const HugInt& src) = default;
HugInt& operator = (const HugInt& src) = default;
// some "C++11" compilers refuse to default the moves
// HugInt(HugInt&& src) = default;
// HugInt& operator = (HugInt&& src) = default;
// cmp(a, b) returns 1 if a>b, 0 if a==b or -1 if a<b
friend int cmp(const HugInt& lh, const HugInt& rh) {
if(lh.sign != rh.sign) return lh.sign > rh.sign ? 1 : -1;
const int cmpmag = cmpMagnitude(lh, rh);
return lh.sign < 0 ? -cmpmag : cmpmag;
}
friend bool operator == (const HugInt& lh, const HugInt& rh) {
return cmp(lh, rh) == 0;
}
friend bool operator != (const HugInt& lh, const HugInt& rh) {
return cmp(lh, rh) != 0;
}
friend bool operator > (const HugInt& lh, const HugInt& rh) {
return cmp(lh, rh) == 1;
}
friend bool operator < (const HugInt& lh, const HugInt& rh) {
return cmp(lh, rh) == -1;
}
friend bool operator >= (const HugInt& lh, const HugInt& rh) {
return cmp(lh, rh) != -1;
}
friend bool operator <= (const HugInt& lh, const HugInt& rh) {
return cmp(lh, rh) != 1;
}
// negate operator
HugInt operator - () const {
HugInt neg;
neg.integer = integer;
neg.sign = -sign;
return neg;
}
// subtract-assign operator
HugInt& operator -= (const HugInt &op2) {
if(op2.sign == 0) { // op2 is zero, do nothing
return *this;
}
if(sign == 0) { // *this is zero, set *this to negative op2
integer = op2.integer;
sign = -op2.sign;
return *this;
}
if(sign == op2.sign) { // same signs: use magnitude subtratction
subMagnitude(op2);
return *this;
}
// opposite signs here: needs magnitude addition (but not implemented)
addMagnitude(op2);
return *this;
}
friend HugInt operator - (const HugInt& lh, const HugInt& rh) {
// a - b uses the -= operator to avoid duplicate code
HugInt result{lh};
return result -= rh;
}
// overload stream output operator for HugInt values
friend std::ostream& operator << (std::ostream& os, const HugInt& hi) {
// assumes decimal output and class radix is 10
if(hi.integer.getSize() == 0) return os << '0';
if(hi.sign < 0) os << '-';
for(int i=hi.integer.getSize()-1; i+1; --i) {
os << char('0' + int(hi.integer[i]));
}
return os;
}
};
int main() {
using HugeInt = HugInt<char>;
{
HugeInt a = "21758612232416725117133766166700 1758612232416725117155428849047";
unsigned short b = 55427;
HugeInt c = a - b;
std::cout << a << " - " << b << " = \n" << c << '\n';
}
std::cout << '\n';
{
short a = 6521;
HugeInt b = 1234567;
HugeInt c = a - b;
std::cout << a << " - " << b << " = \n" << c << '\n';
}
}
有了上述内容,我可以看到一个google-sign-in按钮,它会打开一个弹出窗口接受凭据并让我登录。但我希望在登录成功时触发 onSignIn 方法,这没有发生。 有没有人对此有任何指示?
使用safari,chrome和firefox浏览器在osx上的apache服务器上尝试
答案 0 :(得分:2)
您应该在head标记
中添加platform.js脚本<html>
<head>
<meta name="google-signin-client_id" content="MY_CLIENT_ID.apps.googleusercontent.com" />
<script src="https://apis.google.com/js/platform.js" async defer> </script>
</head>
<body>
<div class="g-signin2" data-onsuccess="onSignIn"></div>
<script type="text/javascript">
function onSignIn(googleUser) {
console.log("Succesfully Singed in!!!");
}
</script>
</body>
</html>
答案 1 :(得分:2)
就我而言:The callback function was inside the body tag
。
如果回调函数在body标签中,则无法使用,请将其移到head标签中。
答案 2 :(得分:1)
回答太晚了,但我认为有人会需要这个:
答案 3 :(得分:0)
检查Developers Console并查看授权重定向URI 是否指向您正在运行JavaScript的来源?
答案 4 :(得分:0)
就我而言,成功事件没有触发,因为我试图从页面上包含的外部js文件中连接函数。由于某些原因,只有在挂钩的函数出现在同一页面上时,回调函数才起作用。
以前从未见过这样的东西。我想知道他们如何检查这一点。