Uau - legal! Obrigado. E eu pensei - isso conta sempre. Sim, bem, é lógico, você já pode calculá-lo em tempo de compilação. Então, assim:
Mas seria mais correto escreverDBL_MANT_DIG ao invés de 53.
Caso de ganho mínimo, se todos os valores de duplo forem fracionários.
1. Sua implementação está incompleta, só pode ser usada se a faixa de valores possíveis for conhecida antecipadamente.
Aqui está o código da implementação completa
union Double
{
double x;
ulong ul;
};
double Ceil (double x)
{
Double dbl;
dbl.x=x;
//--- убираем знакulong uv=dbl.ul & 0x7fffffffffffffff;
//--- значение меньше единицыif(uv<0x3FF0000000000000)
{
//--- ноль возвращаем как естьif(!uv)
return(x);
//--- оставим только знак
dbl.ul &= 0x8000000000000000;
//--- положительные округляем до 1.0if(!dbl.ul)
return(1.0);
//--- отрицательные округляем до -0.0return(dbl.x);
}
//--- полностью целое числоif(uv>=0x4340000000000000)
return(x);
//--- получим знакulong sign=dbl.ul&0x8000000000000000;
//--- IEEE магия (для домашнего изучения)ulong nuv=uv & ~(((ulong)1<<(51-char(uv>>52)))-1);
//--- для положительного значенияif(!sign)
{
dbl.ul=nuv;
//--- добавим единицу, если число не целоеif(nuv!=uv)
dbl.x+=1.0;
}
else
{
//--- для отрицательного просто добавим знак
dbl.ul=nuv|sign;
}
//--- return(dbl.x);
}
2018.08.2716:11:15.014 TestRound (EURUSD,H1) Время выполнения ceil = 6.382 наносекунд, Контрольная сумма = 5071042018.08.2716:11:15.028 TestRound (EURUSD,H1) Время выполнения Ceil = 4.792 наносекунд, Контрольная сумма = 507104
2. As funções auto-escritas são significativamente mais lentas do que as funções incorporadas quando compiladas para depuração, quando as otimizações são desativadas.
Eu queria especular sobre o tema: você não consegue entender a Rússia com sua mente, mas então voltei minha atenção para o tema: implementações alternativas de funções/abordagens padrão.
Em geral, sobre o tema do fio, consegui implementar uma abordagem completamente alternativa ao desenho em tela. Sem utilizar a classe CCanvas.
Ou seja, não para modificar um conjunto separado de funções, mas para criar um mecanismo de desenho completo, que consiste em um único bloco.
(É claro que dificilmente posso demonstrar tudo isso no código, pois há muito código e é escrito de forma não padronizada, mas eu gostaria de dizer a vocês em geral).
Portanto:
1. o bloco (função)
void Нарисовать_элемент(int Канвас, int Элемент = 0)
aceita apenas 2 parâmetros - Kanvas e Elemento.
Kanvas é um projeto de MT,
Elemento é um desenho.
2. Cada projeto MT tem seu próprio recurso atribuído a ele. Ele é imediatamente carregado na "matriz de pixels" usando ResourceReadImage(); se o recurso ainda não existir, é colocada uma bandeira, que posteriormente determinará o alcance do ciclo sobre o núcleo.
3. O núcleo, é um conjunto de propriedades de todos os elementos. Ele contém dados sobre os tamanhos dos objetos e cores para diferentes estados. E muitos outros dados. Existem 235 propriedades no total para cada objeto. Ao mesmo tempo, cada elemento (dependendo do tipo) pode conter de um a 11 objetos (não há limitação).
4. No bloco de desenho, cada objeto implica um "Detalhe" do desenho. Portanto, o ciclo por objeto no núcleo, é um ciclo de desenho no qual é criada a imagem de cada Detalhe. Se uma Tela ainda não tiver sido criada, um ciclo completo é feito apenas sobre todos os detalhes dessa Tela. A afiliação ao Kanvas é prescrita no kernel, para cada Detalhe. Ou seja, todos os Kanvases (e peças) têm seus próprios números seqüenciais. Através destes números é possível desenhar apenas o conteúdo do Kanvas necessário.
4. Se um Kanvas já existe e sua imagem é carregada em uma matriz de pixels, e só precisamos redesenhar um único elemento (em um evento de mudança de cor, por exemplo), então o alcance do loop central é reduzido aos limites do elemento único cujo número foi obtido pela função de desenho.
O desenho em si é simples. É um ciclo através das células de uma matriz unidimensional da esquerda para a direita. Antes que o ciclo seja definido:
1. A célula de partida (ponto A).
2. A célula final (Ponto B).
3. Chegar ao fim.
É difícil resumir a operação de um bloco de 1500 linhas de código em poucas palavras. É uma função, que vem crescendo e polindo há 20 meses. Eu o conheço quase de cor, o que torna fácil continuar desenvolvendo-o.
Ao utilizar o núcleo e o foco (colocando variáveis importantes no escopo global), o bloco adquire enormes possibilidades. Seus limites não são visíveis para mim até hoje.
Essa é a alternativa para a abordagem padrão do desenho kanvas.
zy. Se estiver interessado nos detalhes, eu posso explicar.
1. Sua implementação está incompleta e só pode ser usada se o intervalo de valores possíveis for conhecido antecipadamente.
Aqui está o código para a implementação completa
Mais uma vez, obrigado pelo código. Tenho me intrigado com estas máscaras de bit como se fossem duplas. Acontece que não é tão fácil como eu pensava antes. Eu ajustei ligeiramente minha versão à sua. Havia apenas uma diferença: sua versão retornou com valores -1>x>0 Ceil(-0,1)= - 0,0, enquanto que a minha retornou 0,0. Embora eu não saiba quando pode ser útil.
double Ceil(double x)
{
if(x!=x || // если x = NaN(SNaN) т.е. переполнение или ошибка
x> (long)1<<53 || // или число x положительное и превышает максимальную возможную мантиссу, т.е. дробная часть в x точно отсутствует
x<-(long)1<<53) // или число x отрицательное и превышает максимальную возможную мантиссу, т.е. дробная часть в x точно отсутствует return(x);
if(x-(long)x>0) // Если число положительное или дробная часть не равна нулюreturn(long)x+1.0; // добавляем к бездробной части 1elseif(x>-1 && x<0) // Если -1 < x < 0return -0.0; // то возвращаем -0.0elsereturn (double)long(x);
}
Eu escrevi um roteiro (anexo), que confirma 100% de identidade com sua versão. Mas esta variante é mais rápida, mais compacta e, em minha opinião, mais legível.
Observe que nem mesmo uma única variável é criada no corpo da função, enquanto sua versão cria 4 variáveis de 8 bytes. Talvez eu esteja errado?
Resultados quando a entrada x tem sempre uma parte fracionária:
2018.08.2718:42:37.616 TestCeil (EURUSD,M1) Время выполнения функции CeilI = 1.321 наносекунд, Контрольная сумма = 5250492895.02018.08.2718:42:37.619 TestCeil (EURUSD,M1) Время выполнения функции CeilN = 1.094 наносекунд, Контрольная сумма = 5250492895.02018.08.2718:42:37.623 TestCeil (EURUSD,M1) Время выполнения функции ceil = 2.962 наносекунд, Контрольная сумма = 5250492895.02018.08.2718:42:37.623 TestCeil (EURUSD,M1) Идет бесконечный поиск расхождения по случайным числам double ... Прервите скрипт, когда надоест ждать
Os resultados quando a entrada x tem uma parte fracionária são raros:
2018.08.2718:49:45.734 TestCeil (EURUSD,M1) Время выполнения функции CeilI = 0.307 наносекунд, Контрольная сумма = 1.15583114403606 e+232018.08.2718:49:45.736 TestCeil (EURUSD,M1) Время выполнения функции CeilN = 0.102 наносекунд, Контрольная сумма = 1.15583114403606 e+232018.08.2718:49:45.738 TestCeil (EURUSD,M1) Время выполнения функции ceil = 1.026 наносекунд, Контрольная сумма = 1.15583114403606 e+232018.08.2718:49:45.738 TestCeil (EURUSD,M1) Идет бесконечный поиск расхождения по случайным числам double ... Прервите скрипт, когда надоест ждать
Ilyas:
2. As funções auto-escritas são significativamente mais lentas do que as incorporadas quando da compilação para depuração, quando as otimizações são desativadas.
Não está claro porque a velocidade é necessária para a depuração. Mas se você realmente precisar, você pode usar a construção:
#ifdef _DEBUG x=Ceil(y);
#else x=ceil(y); #endif
E há mais uma coisa que eu não entendo:
Por que a documentação e o DBL_MANT_DIG real = 53 ?
como de acordo com a mesma Wikipédia= 52. E, ao que parece, decorre do seu código que 52 também ?
Uau - legal! Obrigado. E eu pensei - isso conta sempre. Sim, bem, é lógico, você já pode calculá-lo em tempo de compilação.
Então, assim:
Mas seria mais correto escreverDBL_MANT_DIG ao invés de 53.
Caso de ganho mínimo, se todos os valores de duplo forem fracionários.
1. Sua implementação está incompleta, só pode ser usada se a faixa de valores possíveis for conhecida antecipadamente.
Aqui está o código da implementação completa
2. As funções auto-escritas são significativamente mais lentas do que as funções incorporadas quando compiladas para depuração, quando as otimizações são desativadas.
1. Sua implementação está incompleta e só pode ser usada se o intervalo de valores possíveis for conhecido antecipadamente.
Aqui está o código para a implementação completa
2. As funções auto-escritas são muito mais lentas do que as incorporadas quando a compilação para depuração quando as otimizações são desativadas.
Muito obrigado, Ilyas, pelo excelente código.
É claro, é uma grande ajuda aqui.
Estou estudando isso.
Isso não é a mesma coisa?Nikolai, oi. Vejo que você está trabalhando em gráficos, mas não entendo totalmente qual é a tarefa real. Em que você está trabalhando?
Acelerando as funções de renderização?
Em geral, sobre o tema do fio, consegui implementar uma abordagem completamente alternativa ao desenho em tela. Sem utilizar a classe CCanvas.
Ou seja, não para modificar um conjunto separado de funções, mas para criar um mecanismo de desenho completo, que consiste em um único bloco.
(É claro que dificilmente posso demonstrar tudo isso no código, pois há muito código e é escrito de forma não padronizada, mas eu gostaria de dizer a vocês em geral).
Portanto:
1. o bloco (função)
aceita apenas 2 parâmetros - Kanvas e Elemento.
2. Cada projeto MT tem seu próprio recurso atribuído a ele. Ele é imediatamente carregado na "matriz de pixels" usando ResourceReadImage(); se o recurso ainda não existir, é colocada uma bandeira, que posteriormente determinará o alcance do ciclo sobre o núcleo.
3. O núcleo, é um conjunto de propriedades de todos os elementos. Ele contém dados sobre os tamanhos dos objetos e cores para diferentes estados. E muitos outros dados. Existem 235 propriedades no total para cada objeto. Ao mesmo tempo, cada elemento (dependendo do tipo) pode conter de um a 11 objetos (não há limitação).
4. No bloco de desenho, cada objeto implica um "Detalhe" do desenho. Portanto, o ciclo por objeto no núcleo, é um ciclo de desenho no qual é criada a imagem de cada Detalhe. Se uma Tela ainda não tiver sido criada, um ciclo completo é feito apenas sobre todos os detalhes dessa Tela. A afiliação ao Kanvas é prescrita no kernel, para cada Detalhe. Ou seja, todos os Kanvases (e peças) têm seus próprios números seqüenciais. Através destes números é possível desenhar apenas o conteúdo do Kanvas necessário.
4. Se um Kanvas já existe e sua imagem é carregada em uma matriz de pixels, e só precisamos redesenhar um único elemento (em um evento de mudança de cor, por exemplo), então o alcance do loop central é reduzido aos limites do elemento único cujo número foi obtido pela função de desenho.
O desenho em si é simples. É um ciclo através das células de uma matriz unidimensional da esquerda para a direita. Antes que o ciclo seja definido:
1. A célula de partida (ponto A).
2. A célula final (Ponto B).
3. Chegar ao fim.
É difícil resumir a operação de um bloco de 1500 linhas de código em poucas palavras. É uma função, que vem crescendo e polindo há 20 meses. Eu o conheço quase de cor, o que torna fácil continuar desenvolvendo-o.
Ao utilizar o núcleo e o foco (colocando variáveis importantes no escopo global), o bloco adquire enormes possibilidades. Seus limites não são visíveis para mim até hoje.
Essa é a alternativa para a abordagem padrão do desenho kanvas.
zy. Se estiver interessado nos detalhes, eu posso explicar.
É assim que o início do bloco se parece:
1. Sua implementação está incompleta e só pode ser usada se o intervalo de valores possíveis for conhecido antecipadamente.
Aqui está o código para a implementação completa
Mais uma vez, obrigado pelo código. Tenho me intrigado com estas máscaras de bit como se fossem duplas. Acontece que não é tão fácil como eu pensava antes.
Eu ajustei ligeiramente minha versão à sua. Havia apenas uma diferença: sua versão retornou com valores -1>x>0 Ceil(-0,1)= - 0,0, enquanto que a minha retornou 0,0. Embora eu não saiba quando pode ser útil.
E você recebe o seguinte:
A mesma coisa, apenas legível e com comentários:
Eu escrevi um roteiro (anexo), que confirma 100% de identidade com sua versão.
Mas esta variante é mais rápida, mais compacta e, em minha opinião, mais legível.
Observe que nem mesmo uma única variável é criada no corpo da função, enquanto sua versão cria 4 variáveis de 8 bytes.
Talvez eu esteja errado?
Resultados quando a entrada x tem sempre uma parte fracionária:
Os resultados quando a entrada x tem uma parte fracionária são raros:
2. As funções auto-escritas são significativamente mais lentas do que as incorporadas quando da compilação para depuração, quando as otimizações são desativadas.
Não está claro porque a velocidade é necessária para a depuração.
Mas se você realmente precisar, você pode usar a construção:
E há mais uma coisa que eu não entendo:
Por que a documentação e o DBL_MANT_DIG real = 53 ?
como de acordo com a mesma Wikipédia= 52.
E, ao que parece, decorre do seu código que 52 também ?
Nikolai, oi. Vejo que você está trabalhando em gráficos, mas não entendo totalmente qual é a tarefa real. Em que você está trabalhando?
Acelerando as funções de renderização?
Olá Piotr!
Responderei pessoalmente.
E há mais uma coisa que eu não entendo:
Por que a documentação e o DBL_MANT_DIG real = 53 ?
enquanto que de acordo com o mesmo wikipedia= 52.
E parece que seu código também implica que é 52 ?
Você mesmo já tentou encontrar a resposta para a pergunta?
Dica: Na busca do google, digite "DBL_MANT_DIG 53 52".