Сравните дважды в проблеме точности VBA

В документации для String.Split есть несколько полезных замечаний, относящихся к этой проблеме, хотя перед тем, как это обнаружить, я написал следующее.

Один из способов сделать это - найти разделитель с помощью метода String.IndexOf - вы можете указать индекс, с которого начинается поиск, так что можно пропустить пункты без необходимости просматривать каждый персонаж. (Проверка каждого символа происходит за кулисами, но это немного быстрее, чем делать это самостоятельно.)

Я придумал метод расширения, добавив новый класс с именем "ExtensionMethods.cs" в решение с помощью это содержание:

namespace ExtensionMethods
{
    public static class MyExtensions
    {
        /// 
        /// Get the nth item from a delimited string.
        /// 
        /// The string to retrieve a delimited item from.
        /// The character used as the item delimiter.
        /// Zero-based index of item to return.
        /// The nth item or an empty string.
        public static string Split(this string s, char delimiter, int n)
        {

            int pos = pos = s.IndexOf(delimiter);

            if (n == 0 || pos < 0)
            { return (pos >= 0) ? s.Substring(0, pos) : s; }

            int nDelims = 1;

            while (nDelims < n && pos >= 0)
            {
                pos = s.IndexOf(delimiter, pos + 1);
                nDelims++;
            }

            string result = "";

            if (pos >= 0)
            {
                int nextDelim = s.IndexOf(delimiter, pos + 1);
                result = (nextDelim < 0) ? s.Substring(pos + 1) : s.Substring(pos + 1, nextDelim - pos - 1);
            }

            return result;
        }

    }
}

И небольшая программа для его проверки:

using System;
using System.Diagnostics;
using System.Linq;
using ExtensionMethods;

namespace ConsoleApp1
{

    class Program
    {

        static void Main(string[] args)
        {
            // test data...
            string s = string.Join(";", Enumerable.Range(65, 26).Select(c => (char)c));
            s = s.Insert(3, ";;;");

            string o = "";

            Stopwatch sw = new Stopwatch();

            sw.Start();
            for (int i = 1; i <= 1000000; i++) {
                o = s.Split(';', 21);
            }
            sw.Stop();
            Console.WriteLine("Item directly selected: " + sw.ElapsedMilliseconds);

            sw.Restart();
            for (int i = 1; i <= 1000000; i++) {
                o = s.Split(';')[21];
            }
            sw.Stop();
            Console.WriteLine("Item from split array:  " + sw.ElapsedMilliseconds + "\r\n");


            Console.WriteLine(s);
            Console.WriteLine(o);

            Console.ReadLine();

        }
    }
}

Пример вывода:

Элемент, выбранный напрямую: 1016
[ 115] Элемент из разделенного массива: 1345

A; B ;;;; C; D; E; F; G; H; I; J; K; L; M; N; O; P; Q ; R; S; T; U; V; W; X; Y; Z
S

blockquote>

Ссылка: Как выполнить и вызвать a Пользовательский метод расширения (Руководство по программированию в C #)

12
задан Eric 24 October 2008 в 22:37
поделиться

4 ответа

Вы не можете сравнить значения с плавающей точкой для равенства. См. эту статью о "Сравнении чисел с плавающей точкой" для обсуждения того, как обработать основную ошибку.

Это не столь просто как по сравнению с постоянным допуском на погрешность, если Вы не знаете наверняка, что абсолютный диапазон плаваний заранее.

14
ответ дан 2 December 2019 в 04:26
поделиться

Никогда не мудро выдержать сравнение, удваивается на равенстве.

Некоторые десятичные значения отображаются на несколько представлений с плавающей точкой. Так 0.6 не всегда равно другим 0.6.

Если мы вычитаем один из другого, мы, вероятно, получаем что-то как 0,00000000051.

Мы можем теперь определить равенство как наличие различия, меньшего что определенный допуск на погрешность.

5
ответ дан 2 December 2019 в 04:26
поделиться

Как был указан, много десятичных чисел не могут быть представлены точно как традиционные типы с плавающей точкой. В зависимости от природы Вашего пространства задач можно быть более обеспеченным использованием Десятичного типа VBA, который может представить десятичные числа (базируйтесь 10) с идеальной точностью до определенной десятичной точки. Это часто делается для представления денег, например, где 2-разрядная десятичная точность часто желаема.

Dim a as Decimal
Dim b as Decimal
a = 0.15
b = 0.01
3
ответ дан 2 December 2019 в 04:26
поделиться

Тип данных Валюты может быть хорошей альтернативой. Это обрабатывает относительно большие количества с фиксированными четырьмя точностью цифры.

1
ответ дан 2 December 2019 в 04:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: