Три нестандартных типа чисел в JavaScript и две библиотеки

    В JavaScript по умолчанию есть один тип чисел — Number. Хотя он конечно делится на Int и Float, хотя выражается это в немногом (например, в функциях parseInt — parseFloat).
    При этом большие числа (и Int и Float) укорачиваются, а дроби приводятся к десятичным и округляются. И то и другое не всегда хорошо, так что появились библиотеки, которые предлагают новые классы для необычных чисел.

    BigInt

    Числа (и Int и Float) укорачиваются до 15 символов. При этом в Int остальные цифры хранятся в качестве нулей. Пример:
    >> 100000000000000000111
      100000000000000000000
    

    Библиотека называется BigNumber, числа нужно передавать в форме строки. Используем:
    var num = new BigNumber('100000000000000000001');
    num.add(1); // 100000000000000000002
    

    Остальное на странице библиотеки, есть большинство нужных функций (+-*/), принимают числа, строки и те же BigNumber.

    BigFloat

    Также есть Float, там тоже 15 символов, но при этом лишние цифры просто выбрасываются.
    >> 3.14159265358979323
      3.141592653589793
    

    Можно использовать ту же библиотеку, в том же формате:
    var pi = new BigNumber('3.14159265358979323');
    pi.add('0.00000000000000003'); // 3.14159265358979326
    


    Fraction

    Третий тип — это дроби. Число округляется. И из-за этого результат может испортиться.
    >> 1/3
      0.3333333333333333
    
    >> 1/3 + 2/3
      1
    
    >> 0.3333333333333333 + 0.6666666666666666
      1
    


    И у нас есть библиотека Fraction.js.
    var a = new Fraction(1,3);
    a.add( new Fraction(2,3) ); // 1
    

    На этом всё

    Спасибо за внимание

    Similar posts

    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 21

      0
      >>100000000000000000000
      для таких числе
      .toFixed(/* количество знаков после запятой */)
      
        0
        сорри немного затупил показалось что там запята)=)
        –8
        Почему все эти люди не используют самовызывающийся конструктор Джона Резига? Разве их самих не задалбывает всякий раз записывать «new» при создании переменной нового типа?
          +3
          А какие преимущества это дает, кроме отсутствия слова 'new'? Усложнение и большая запутанность кода?
            +9
            Представте себе — не задалбывает. Потому что я вижу что я создаю новый обьект а не вызываю функцию.
              0
              Вызывая функцию на подобие $('.some-class'), я тоже вижу, что создаю объект, так как я знаю, что функции могут создавать новые объекты.
                0
                Явное лучше неявного.
                0
                Питон с вами не согласен.
                  0
                  Мне главное чтоб JavaSript был согласен.
                    0
                    а javascript пофигу вообще =) new не new, просто конструкция немного упрощает возврат результата.
                    function a()
                    {
                        return {'a':'b'}
                    } 
                    
                0
                Не стоит поощрять ошибки и пользоваться такими вещами.
                  +6
                  Не стоит поощрять ошибки и пользоваться такими вещами.


                  О каких ошибках вы говорите?

                  Когда функция-конструктор вызывается как часть выражения с new, то это конструктор, который инициализирует создание нового объекта.

                  Далее в качестве примера, предлагаю кратко рассмотреть поведение предопределенных конструкторов в ECMAScript

                  Вызов конструктора в качестве функции (без оператора new) для типов Number, String и Boolean приводит к неявному преобразованию типов:

                  typeof Number([])      // number
                  typeof new Number([])  // object
                  
                  //...
                  


                  Такие операции преобразования типов в ECMAScript выполняется за счет наличия внутреннего метода [[DefaultValue]], который для нативных объектов возвращает примитивное значение в строгом соответствии с таблицами преобразований для внутренних методов ToBoolean, ToNumber, ToString и ToObject.

                  Для получения значения вызываются методы valueOf() или toString().

                  Смоделировать подобное поведение для пользовательских объектов не составит большого труда:

                  var object = {
                  	property: 1,
                  	valueOf: function() {
                  		return this.property;
                  	}
                  };
                  
                  console.log(+object); // 1
                  


                  Такое преобразование происходит за счет активации внутреннего метода ToPrimitive, который в свою очередь неявно вызывает метод valueOf().

                  Теперь давайте рассмотрим более объектно-ориентированный способ:

                  var Foo = function(param) {
                  	if(this instanceof Foo)
                  		return this.param;
                  	else
                  		return param || 1;
                  };
                  
                  Foo.prototype.valueOf = function() {
                  	return this.param || 1;
                  };
                  
                  console.log(Foo());       // 1
                  console.log(Foo(10));     // 10
                  console.log(new Foo);     // Object
                  console.log(+new Foo);    // 1
                  console.log(new Foo + 1); // 2
                  


                  Помимо примитивных значений есть еще объектные:

                  var object = new Object({property: 1});
                  console.log(object.property) // 1
                  

                  В результате этой операции аргумент, переданный в конструктор, активирует внутренний метод ToObject, вследствие чего возвращается объектное значение. При этом, если в конструктор был передан объект, то операции конвертирования типов не происходит.

                  Иными словами, в Object мы можем передать не только объект, но и такие примитивные типы, как Boolean, Number и String:

                  var boolean = new Object(true);     // [object Boolean]
                  var number  = new Object(1);        // [object Number]
                  var string  = new Object('string'); // [object String]
                  

                  Использование оператора new в данном случае опционально, как и с другими конструкторами, такими как Array, Function и RegExp:

                  new Array(1, 2);  // [object Array]
                  new Function(''); // [object Function]
                  new RegExp('');   // [object RegExp]
                  

                  В этом случае отсутствие оператора new трактуется как вызов конструктора в качестве функции.
                  Однако, возможны исключения когда наличие оператора new действительно влияет на результат:

                  var type = function(object) {
                  	return Object.prototype.toString.call(object);
                  };
                  
                  type(new Date);  // [object Date]
                  type(Date);      // [object Function]
                  type(Date());    // [object String]
                  type(+new Date); // [object Number]
                  


                  Во-первых, прошу обратить внимание на то, что все четыре вызова возвращают разные результаты. У неподготовленных пользователей, вероятно, это приведет к баттхёрту :)

                  Примечание: особо стоит отметить, то что объект Math не имеет внутреннего свойства [[Construct]] из-за чего невозможно использовать этот объект как конструктор с оператором new.
                  Также объект Math не имеет внутреннего свойства [[Call]] из-за чего невозможно вызывать этот объект как функцию!

                  Таким образом, можно сказать, что для построения архитектуры собственных конструкторов, использование fallback'a (вызов конструктора в качестве функции без оператора new) не может считаться ошибкой если он спроектирован грамотно.
                  0
                  его решение использует arguments.calee(), что в будущей версии JavaScript запрещено, как я понял

                  developer.mozilla.org/en/JavaScript/Reference/Functions_and_function_scope/arguments/callee
                    0
                    strict mode только
                      0
                      Подсознательно я стремлюсь к работе моего кода в самых суровых условиях.
                      +1
                      В смысле запрещено только в строгом режиме
                    0
                    Я хотел сказать про вызовы конструкторов классов, вроди:
                    var MyConstructor = function(){};
                    MyConstructor();
                    new MyConstructor();
                    

                    напримерн может случится вот так:
                    MyConstructor.prototype.alert = function(){ return 1+1;};
                    

                    (хотел сказать что вызов функции конструктора без new установит ссылку на this = window может как то запутанно объясняю)
                      0
                      есть библиотека Fraction.js.
                      не знал, пригодится
                        +1
                        Кстати есть ещё bigdecimal.js для больших чисел
                          0
                          А, да, ещё модуль в Dojo Toolkit — dojox.math.BigInteger
                          +1
                          BigInt.js — отличная библиотека для криптологов. Очень долго с ней работал.

                          Only users with full accounts can post comments. Log in, please.